📅  最后修改于: 2023-12-03 15:05:57.478000             🧑  作者: Mango
在 Windows 上,有一些 Action 和任务需要以管理员身份运行。但如果你的程序没有显式地要求以管理员身份运行,那么用户通过双击或者简单提权的方式运行程序可能会遇到权限不足的问题。
如何使程序以管理员身份运行呢?本文将介绍一种能够检查并获取管理员权限的方法,并且让程序以管理员身份运行。
我们可以使用 Windows API 来获取当前用户的安全令牌。代码如下所示:
include windows.inc
include user32.inc
include kernel32.inc
.data
String db 20 dup (0)
TokenHandle HANDLE ?
PrivilegeLUID LUID of _TOKEN_PRIVILEGES
NewStateTOKEN_PRIVILEGES ?
OldStateTOKEN_PRIVILEGES ?
.data?
ReturnLength dd ?
.code
start:
; 打开当前进程的访问令牌
invoke GetCurrentProcess
invoke OpenProcessToken, eax, TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES, addr TokenHandle
.if eax == false
invoke MessageBox, 0, addr OpenTokenErrorMsg, addr AppName, MB_ICONERROR or MB_OK
jmp end
.endif
; 获取管理员权限的 LUID
invoke LookupPrivilegeValue, 0, SE_DEBUG_NAME, addr PrivilegeLUID
.if eax == false
invoke MessageBox, 0, addr LookupPrivilegeErrorMsg, addr AppName, MB_ICONERROR or MB_OK
jmp close_token_and_end
.endif
; 获取当前进程的安全令牌信息
invoke GetTokenInformation, TokenHandle, TokenPrivileges, 0, 0, addr ReturnLength
mov eax, ReturnLength
invoke GlobalAlloc, GPTR, eax
mov NewStateTOKEN_PRIVILEGES, eax
invoke GetTokenInformation, TokenHandle, TokenPrivileges, NewStateTOKEN_PRIVILEGES, eax, addr ReturnLength
.if eax == false
invoke MessageBox, 0, addr GetTokenInformationErrorMsg, addr AppName, MB_ICONERROR or MB_OK
jmp free_mem_close_token_and_end
.endif
; 获取 LUID 所对应的权限的 flag,设置权限
mov edi, NewStateTOKEN_PRIVILEGES
mov ecx, dword ptr [edi]
mov edx, PrivilegeLUID
mov esi, edi
sub esi, 4
mov ebx, dword ptr [esi]
mov eax, ecx
.process_privileges_loop:
mov esi, edi
add esi, eax
mov eax, dword ptr [esi]
cmp eax, edx
.if eax == edx
invoke RtlCopyMemory, addr ebx, addr eax, 4
mov dword ptr [ebx + 4], SE_PRIVILEGE_ENABLED
jmp privileges_processed
.endif
add ecx, 4
cmp ecx, dword ptr [edi-4]
jb process_privileges_loop
privileges_processed:
; 将更改后的权限信息应用到进程
invoke AdjustTokenPrivileges, TokenHandle, false, NewStateTOKEN_PRIVILEGES, 0, addr OldStateTOKEN_PRIVILEGES, addr ReturnLength
.if eax == false
invoke MessageBox, 0, addr AdjustTokenPrivilegesErrorMsg, addr AppName, MB_ICONERROR or MB_OK
.endif
free_mem_close_token_and_end:
invoke GlobalFree, NewStateTOKEN_PRIVILEGES
close_token_and_end:
; 关闭访问令牌
invoke CloseHandle, TokenHandle
end:
invoke ExitProcess, 0
接下来,我们将使用该方法来启动一个新的进程,该进程也会以管理员身份运行。代码如下所示:
include windows.inc
include user32.inc
include kernel32.inc
.data
AppName db 'My Application',0
CommandLine db 'notepad.exe',0
.code
start:
; 检查并获取管理员权限
; ...
; 启动新进程以获取管理员权限
invoke CreateProcessAsUser, 0, addr CommandLine, 0, 0, 0, 0, 0, 0, 0, addr StartupInfo, addr ProcessInfo
.if eax == false
invoke MessageBox, 0, addr CreateProcessErrorMsg, addr AppName, MB_ICONERROR or MB_OK
jmp end
.endif
invoke CloseHandle, ProcessInfo.hProcess
invoke CloseHandle, ProcessInfo.hThread
end:
invoke ExitProcess, 0
现在你的程序已经以管理员身份成功运行了!