作者: 一块三毛钱
邮件: zhongts@163.com
日期: 2005.1.15

本文总结了 4 种方法获得 SYSTEM 权限来运行 regedit.exe 文件,源代码很容易修改成命令行方式运行指定的程序。

1. 以服务方式运行
2. 添加 ACL 的方法
3. HOOK ZwCreateProcessEx 函数
4. 远程线程的方法

  这几种方法都不是我想出来的,我只不过是总结了一下,用 Win32ASM 重写了代码而以。关于这个大家可以看文章末尾的参考资料。下面简单的分析每一种方法。

1. 以服务方式运行

  因为以服务方式运行程序时,相当于运行程序的是系统进程,所以,被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM 权限。

;@echo off
;goto make
;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys1
;
; 采用以服务方式运行的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib
_ReLaunch proto
CTXT MACRO text
local lbl
.const
lbl db text,0
.code
exitm   
ENDM
.code
start proc
LOCAL   stStartupInfo : STARTUPINFO
LOCAL   procinfo : PROCESS_INFORMATION
invoke  CreateMutex, NULL, TRUE, CTXT("GetSys1_Mutex")
invoke  GetLastError
.if eax==ERROR_ALREADY_EXISTS
invoke  RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
mov     stStartupInfo.cb, sizeof stStartupInfo
invoke  CreateProcess, 0, CTXT("regedit.exe"), 0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
invoke  CloseHandle, procinfo.hProcess
invoke  CloseHandle, procinfo.hThread
.else
invoke  _ReLaunch
.endif
invoke  ExitProcess, NULL
start endp
_ReLaunch proc
LOCAL   hSCManager
LOCAL   hService
LOCAL   szName[MAX_PATH] : byte
invoke  OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
.if eax!=0
mov     hSCManager, eax
invoke  OpenService, hSCManager, CTXT("GetSys1Temp"), DELETE
.if eax!=0
push    eax
invoke  DeleteService, eax
call    CloseServiceHandle
.endif
invoke  GetModuleFileName, NULL, addr szName, MAX_PATH
invoke  CreateService, hSCManager, CTXT("GetSys1Temp"), CTXT("GetSys1 Temp Service"), \
SERVICE_START + SERVICE_QUERY_STATUS + DELETE, \
SERVICE_WIN32_OWN_PROCESS + SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr szName, NULL, NULL, NULL, NULL, NULL
.if eax!=0
mov     hService, eax
invoke  StartService, hService, 0, NULL
invoke  DeleteService, hService
invoke  CloseServiceHandle, hService
.endif
invoke  CloseServiceHandle, hSCManager
.endif
ret
_ReLaunch endp
end start
:make
set path=%path%;c:\masm32\bin
set appname=GetSys1
ml /nologo /c /coff %appname%.bat
link /nologo /subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause

  GetSys1(第一次运行的这个进程 GetSys1 我们称为 A) 开始运行时先创建一个互斥量,接着以服务的方式重新启动自己(又一次运行的进程 GetSys1 我们称为 B),重新运行后的 B 已经具有了 SYSTEM 权限。B 再通过 CreateProcess 函数运行 regedit.exe 程序,因为 B 具有 SYSTEM 权限,所以 regedit.exe 从中继承了 SYSTEM 权限。运行完了 regedit.exe 后 B 结束运行,然后 A 中的 StartService 函数返回,A 结束运行。就是因为 StartService 函数不会直接返回,所以不能够直接通过服务的方式运行 regedit.exe。

2. 添加 ACL 的方法

  主要思想是调用 CreateProcessAsUser 函数来运行程序,CreateProcessAsUser 函数的第一个参数是特定用户的令牌,把这个参数设为具有 SYSTEM 权限的令牌即可。

;@echo off
;goto make
;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys2
;
; 采用添加 ACL 的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\accctrl.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib
_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName proto :DWORD
_ModifySecurity proto :DWORD,:DWORD
CTXT MACRO text
local lbl
.const
lbl db text,0
.code
exitm   
ENDM
ACL STRUCT
AclRevision     BYTE  ?
Sbz1            BYTE  ?
AclSize         WORD  ?
AceCount        WORD  ?
Sbz2            WORD  ?
ACL ENDS
PACL typedef PTR ACL
SecurityImpersonation   equ 2
.code
start proc
LOCAL   hProc
LOCAL   hToken, hNewToken
LOCAL   stStartupInfo : STARTUPINFO
LOCAL   procinfo : PROCESS_INFORMATION
sub     eax, eax
mov     hProc, eax
mov     hToken, eax
mov     hNewToken, eax
invoke  RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke  RtlZeroMemory, addr procinfo, sizeof procinfo
invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
invoke  _GetPidFromProcName, CTXT("lsass.exe")
invoke  OpenProcess, PROCESS_QUERY_INFORMATION, 0, eax
test    eax, eax
jz      _exit
mov     hProc, eax
invoke  OpenProcessToken, hProc, READ_CONTROL+WRITE_DAC, addr hToken
test    eax, eax
jz      _exit
invoke  _ModifySecurity, hToken, TOKEN_ALL_ACCESS
test    eax, eax
jz      _exit
invoke  CloseHandle, hToken
mov     hToken, 0
invoke  OpenProcessToken, hProc, TOKEN_ALL_ACCESS, addr hToken
test    eax, eax
jz      _exit
invoke  DuplicateTokenEx, hToken, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, addr hNewToken
test    eax, eax
jz      _exit
invoke  ImpersonateLoggedOnUser, hNewToken
test    eax, eax
jz      _exit
mov     stStartupInfo.cb, sizeof stStartupInfo
invoke  CreateProcessAsUser, hNewToken, 0, CTXT("regedit.exe"), 0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
test    eax, eax
jz      _exit
invoke  CloseHandle, procinfo.hProcess
invoke  CloseHandle, procinfo.hThread
_exit:
.if hProc
invoke  CloseHandle, hProc
.endif
.if hToken
invoke  CloseHandle, hToken
.endif
.if hNewToken
invoke  CloseHandle, hNewToken
.endif
invoke  ExitProcess, NULL
start endp
_ModifySecurity proc uses ebx esi edi, hToken:DWORD, dwAccess:DWORD
LOCAL   pSD, pAbsSD
LOCAL   dwSDLength
LOCAL   bDaclPresent, bDaclDefaulted
LOCAL   pAcl : PACL
LOCAL   pNewAcl : PACL
LOCAL   szName[1024] : BYTE
LOCAL   ea : EXPLICIT_ACCESS
LOCAL   pSacl, pOwner, pPrimaryGroup
LOCAL   dwAclSize, dwSaclSize, dwOwnerSize, dwPrimaryGroup
LOCAL   bSuccess
sub     eax, eax
mov     pSD, eax
mov     pAbsSD, eax
mov     dwSDLength, eax
mov     bDaclPresent, eax
mov     bDaclDefaulted, eax
mov     pAcl, eax
mov     pNewAcl, eax
mov     pSacl, eax
mov     pOwner, eax
mov     pPrimaryGroup, eax
mov     dwAclSize, eax
mov     dwSaclSize, eax
mov     dwOwnerSize, eax
mov     dwPrimaryGroup, eax
mov     bSuccess, eax
invoke  GetKernelObjectSecurity, hToken, DACL_SECURITY_INFORMATION, pSD, 0, addr dwSDLength
invoke  LocalAlloc, LPTR, dwSDLength
test    eax, eax
jz      _exit
mov     pSD, eax
invoke  GetKernelObjectSecurity, hToken, DACL_SECURITY_INFORMATION, pSD, dwSDLength, addr dwSDLength
invoke  GetSecurityDescriptorDacl, pSD, addr bDaclPresent, addr pAcl, addr bDaclDefaulted
mov     eax, sizeof szName
push    eax
invoke  GetUserName, addr szName, esp
pop     eax
invoke  BuildExplicitAccessWithName, addr ea, addr szName, dwAccess, GRANT_ACCESS, FALSE
invoke  SetEntriesInAcl, 1, addr ea, pAcl, addr pNewAcl
cmp     eax, ERROR_SUCCESS
jne     _exit
invoke  LocalFree, pAcl
mov     pAcl, 0
invoke  MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl, addr dwSaclSize, \
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup
invoke  LocalAlloc, LPTR, dwSDLength
test    eax, eax
jz      _exit
mov     pAbsSD, eax
invoke  LocalAlloc, LPTR, dwAclSize
test    eax, eax
jz      _exit
mov     pAcl, eax
invoke  LocalAlloc, LPTR, dwSaclSize
test    eax, eax
jz      _exit
mov     pSacl, eax
invoke  LocalAlloc, LPTR, dwOwnerSize
test    eax, eax
jz      _exit
mov     pOwner, eax
invoke  LocalAlloc, LPTR, dwPrimaryGroup
test    eax, eax
jz      _exit
mov     pPrimaryGroup, eax
invoke  MakeAbsoluteSD, pSD, pAbsSD, addr dwSDLength, pAcl, addr dwAclSize, pSacl, addr dwSaclSize, \
pOwner, addr dwOwnerSize, pPrimaryGroup, addr dwPrimaryGroup
invoke  SetSecurityDescriptorDacl, pAbsSD, bDaclPresent, pNewAcl, bDaclDefaulted
invoke  SetKernelObjectSecurity, hToken, DACL_SECURITY_INFORMATION, pAbsSD
mov     bSuccess, 1
_exit:
.if pSD
invoke  LocalFree, pSD
.endif
.if pAcl
invoke  LocalFree, pAcl
.endif
.if pNewAcl
invoke  LocalFree, pNewAcl
.endif
.if pAbsSD
invoke  LocalFree, pAbsSD
.endif
.if pSacl
invoke  LocalFree, pSacl
.endif
.if pOwner
invoke  LocalFree, pOwner
.endif
.if pPrimaryGroup
invoke  LocalFree, pPrimaryGroup
.endif
mov     eax, bSuccess
ret
_ModifySecurity endp
_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL   hToken
LOCAL   tkp : TOKEN_PRIVILEGES
invoke  GetCurrentProcess
mov     edx, eax
invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
mov     tkp.PrivilegeCount, 1
xor     eax, eax
.if bFlags
mov     eax, SE_PRIVILEGE_ENABLED
.endif
mov     tkp.Privileges.Attributes, eax
invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push    eax
invoke  CloseHandle, hToken
pop     eax
ret
_EnablePrivilege endp
_GetPidFromProcName proc lpProcName:DWORD
LOCAL   stProcess : PROCESSENTRY32
LOCAL   hSnapshot
LOCAL   dwProcessID
mov     dwProcessID, 0
invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
mov     stProcess.dwSize, sizeof stProcess
invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov     hSnapshot, eax
invoke  Process32First, hSnapshot, addr stProcess
.while eax
invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
.if eax==0
mov     eax, stProcess.th32ProcessID
mov     dwProcessID, eax
.break
.endif
invoke  Process32Next, hSnapshot, addr stProcess
.endw
invoke  CloseHandle, hSnapshot
mov     eax, dwProcessID
ret
_GetPidFromProcName endp
end start
:make
set path=%path%;c:\masm32\bin
set appname=GetSys2
ml /nologo /c /coff %appname%.bat
link /nologo /subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause

  GetSys2 取得 lsass.exe 进程的令牌,缺省情况下操作这个令牌的权限很小,所以需要先取得操作这个令牌的所有权限。这个任务由函数 _ModifySecurity 来完成。有了权限后,复制一个主令牌,然后在当前线程中扮演 SYSTEM 用户,接着就可以调用 CreateProcessAsUser 函数运行 regedit.exe 程序了。有关安全性编程不清楚的地方可以参考[3]。

3. HOOK ZwCreateProcessEx 函数

  有关这个[1]里面讲得很清楚了,下面直接给出源代码。

;@echo off
;goto make
;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys3
;
; 采用 HOOK ZwCreateProcessEx 函数的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib
_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName proto :DWORD
_HackedZwCreateProcessEx proto
CTXT MACRO text
local lbl
.const
lbl db text,0
.code
exitm   
ENDM
ASMJMP struct
mov_eax         BYTE    ?
address         DWORD   ?
jmp_eax         WORD    ?
ASMJMP ends
.data?
g_hProc dd  ?
g_dwFunc        dd  ?
.code
start proc
LOCAL   osvi : OSVERSIONINFO
LOCAL   lpAsmJmp
LOCAL   mbi : MEMORY_BASIC_INFORMATION
LOCAL   stStartupInfo : STARTUPINFO
LOCAL   procinfo : PROCESS_INFORMATION
sub     eax, eax
mov     lpAsmJmp, eax
invoke  RtlZeroMemory, addr osvi, sizeof osvi
invoke  RtlZeroMemory, addr mbi, sizeof mbi
invoke  RtlZeroMemory, addr stStartupInfo, sizeof stStartupInfo
invoke  RtlZeroMemory, addr procinfo, sizeof procinfo
mov     osvi.dwOSVersionInfoSize, sizeof osvi
invoke  GetVersionEx, addr osvi
cmp     osvi.dwMajorVersion, 5
jnz     _exit
.if osvi.dwMinorVersion==1
mov     g_dwFunc, 30h
.elseif osvi.dwMinorVersion==2
mov     g_dwFunc, 32h
.endif
invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
invoke  _GetPidFromProcName, CTXT("lsass.exe")
test    eax, eax
jz      _exit
invoke  OpenProcess, PROCESS_CREATE_PROCESS, TRUE, eax
test    eax, eax
jz      _exit
mov     g_hProc, eax
invoke  GetModuleHandle, CTXT("ntdll.dll")
mov     edx, eax
invoke  GetProcAddress, edx, CTXT("ZwCreateProcessEx")
mov     lpAsmJmp, eax
invoke  VirtualQuery, lpAsmJmp, addr mbi, sizeof mbi
push    eax
invoke  VirtualProtect, mbi.AllocationBase, mbi.RegionSize, PAGE_EXECUTE_READWRITE, esp
pop     eax
mov     edi, lpAsmJmp
assume  edi : ptr ASMJMP
mov     [edi].mov_eax, 0B8h
mov     [edi].address, offset _HackedZwCreateProcessEx
mov     [edi].jmp_eax, 0E0FFh
mov     stStartupInfo.cb, sizeof stStartupInfo
invoke  CreateProcess, 0, CTXT("regedit.exe"), 0, 0, 0, 0, 0, 0, addr stStartupInfo, addr procinfo
test    eax, eax
jz      _exit
invoke  CloseHandle, procinfo.hProcess
invoke  CloseHandle, procinfo.hThread
_exit:
invoke  ExitProcess, NULL
start endp
_HackedZwCreateProcessEx proc
mov     eax, g_hProc
mov     dword ptr [esp+16], eax
mov     eax, g_dwFunc
lea     edx, dword ptr [esp+4]
int     2Eh
retn    24h
_HackedZwCreateProcessEx endp
_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL   hToken
LOCAL   tkp : TOKEN_PRIVILEGES
invoke  GetCurrentProcess
mov     edx, eax
invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
mov     tkp.PrivilegeCount, 1
xor     eax, eax
.if bFlags
mov     eax, SE_PRIVILEGE_ENABLED
.endif
mov     tkp.Privileges.Attributes, eax
invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push    eax
invoke  CloseHandle, hToken
pop     eax
ret
_EnablePrivilege endp
_GetPidFromProcName proc lpProcName:DWORD
LOCAL   stProcess : PROCESSENTRY32
LOCAL   hSnapshot
LOCAL   dwProcessID
mov     dwProcessID, 0
invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
mov     stProcess.dwSize, sizeof stProcess
invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov     hSnapshot, eax
invoke  Process32First, hSnapshot, addr stProcess
.while eax
invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
.if eax==0
mov     eax, stProcess.th32ProcessID
mov     dwProcessID, eax
.break
.endif
invoke  Process32Next, hSnapshot, addr stProcess
.endw
invoke  CloseHandle, hSnapshot
mov     eax, dwProcessID
ret
_GetPidFromProcName endp
end start
:make
set path=%path%;c:\masm32\bin
set appname=GetSys3
ml /nologo /c /coff %appname%.bat
link /nologo /subsystem:windows %appname%.obj
del %appname%.obj
echo.
pause

4. 远程线程的方法

  通过注入远程线程的方法来运行指定的 regedit.exe 程序,也是相当于运行 regedit.exe 程序的是系统进程,那么 regedit.exe 也就自然而然的继承了系统进程的 SYSTEM 权限。

;@echo off
;goto make
;====================================================================================
; 一块三毛钱
; http://zhongts.yeah.net
; zhongts@163.com
; 2005.1.15
;
; 以 SYSTEM 权限运行程序 - GetSys4
;
; 采用远程线程的方法
;
;====================================================================================
.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\advapi32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\advapi32.lib
includelib c:\masm32\lib\masm32.lib
_EnablePrivilege proto :DWORD,:DWORD
_GetPidFromProcName proto :DWORD
;下面两个宏来源于罗云彬的《Windows 环境下32位汇编程序设计》一书
reverseArgs macro arglist:VARARG
local   txt,count
txt     TEXTEQU <>
count   = 0
for     i,
count   = count + 1
txt     TEXTEQU @CatStr(i,,<%txt>)
endm
if      count GT 0
txt     SUBSTR  txt,1,@SizeStr(%txt)-1
endif
exitm   txt
endm
_invoke macro _Proc,args:VARARG
local   count
count   = 0
%       for     i,< reverseArgs( args ) >
count   = count + 1
push    i
endm
call    dword ptr _Proc
endm
CTXT MACRO text
local lbl
.const
lbl db text,0
.code
exitm   
ENDM
.data?
g_hProcess      dd  ?
g_lpRemoteCode  dd  ?
.code
Remote_code_start       equ this byte
g_lpGetModuleHandleA    dd  ?
g_lpGetProcAddress      dd  ?
g_szKernel32            db  "Kernel32.dll",0
g_szCreateProcessA      db  "CreateProcessA",0
g_lpCreateProcessA      dd  ?
g_szRegedit             db  "Regedit.exe",0
g_szDesktop             db  "WinSta0\Default",0
g_stStartupInfo         STARTUPINFO 
g_procinfo              PROCESS_INFORMATION 
_RemoteThread proc
;       int     3
pushad
call    @F
@@:
pop     ebx
sub     ebx, offset @B
lea     eax, [ebx+g_szKernel32]
_invoke [ebx+g_lpGetModuleHandleA], eax
mov     esi, eax
lea     eax, [ebx+g_szCreateProcessA]
_invoke [ebx+g_lpGetProcAddress], esi, eax
mov     [ebx+g_lpCreateProcessA], eax
lea     eax, [ebx+g_szDesktop]
lea     ecx, [ebx+g_stStartupInfo]
mov     dword ptr [ecx], sizeof g_stStartupInfo
mov     dword ptr [ecx+8], eax
lea     eax, [ebx+g_szRegedit]
lea     edx, [ebx+g_procinfo]
_invoke [ebx+g_lpCreateProcessA], 0, eax, 0, 0, 0, 0, 0, 0, ecx, edx
popad
ret
_RemoteThread endp
Remote_code_end         equ this byte
Remote_code_length      equ offset Remote_code_end - offset Remote_code_start
start proc
invoke  GetModuleHandle, CTXT("kernel32.dll")
mov     ebx, eax
invoke  GetProcAddress, ebx, CTXT("GetModuleHandleA")
mov     g_lpGetModuleHandleA, eax
invoke  GetProcAddress, ebx, CTXT("GetProcAddress")
mov     g_lpGetProcAddress, eax
invoke  _EnablePrivilege, CTXT("SeDebugPrivilege"), TRUE
invoke  _GetPidFromProcName, CTXT("lsass.exe")
invoke  OpenProcess, PROCESS_CREATE_THREAD+PROCESS_VM_OPERATION+PROCESS_VM_WRITE, FALSE, eax
.if eax
mov     g_hProcess, eax
invoke  VirtualAllocEx, g_hProcess, NULL, Remote_code_length, MEM_COMMIT, PAGE_EXECUTE_READWRITE
.if eax
mov     g_lpRemoteCode, eax
invoke  WriteProcessMemory, g_hProcess, g_lpRemoteCode, offset Remote_code_start, Remote_code_length, NULL
mov     eax, g_lpRemoteCode
add     eax, offset _RemoteThread - offset Remote_code_start
invoke  CreateRemoteThread, g_hProcess, NULL, 0, eax, 0, 0, NULL
invoke  CloseHandle, eax
.endif
invoke  CloseHandle, g_hProcess
.endif
invoke  ExitProcess, NULL
start endp
_EnablePrivilege proc szPriv:DWORD, bFlags:DWORD
LOCAL   hToken
LOCAL   tkp : TOKEN_PRIVILEGES
invoke  GetCurrentProcess
mov     edx, eax
invoke  OpenProcessToken, edx, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken
invoke  LookupPrivilegeValue, NULL, szPriv, addr tkp.Privileges.Luid
mov     tkp.PrivilegeCount, 1
xor     eax, eax
.if bFlags
mov     eax, SE_PRIVILEGE_ENABLED
.endif
mov     tkp.Privileges.Attributes, eax
invoke  AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, 0, 0
push    eax
invoke  CloseHandle, hToken
pop     eax
ret
_EnablePrivilege endp
_GetPidFromProcName proc lpProcName:DWORD
LOCAL   stProcess : PROCESSENTRY32
LOCAL   hSnapshot
LOCAL   dwProcessID
mov     dwProcessID, 0
invoke  RtlZeroMemory, addr stProcess, sizeof stProcess
mov     stProcess.dwSize, sizeof stProcess
invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov     hSnapshot, eax
invoke  Process32First, hSnapshot, addr stProcess
.while eax
invoke  lstrcmpi, lpProcName, addr stProcess.szExeFile
.if eax==0
mov     eax, stProcess.th32ProcessID
mov     dwProcessID, eax
.break
.endif
invoke  Process32Next, hSnapshot, addr stProcess
.endw
invoke  CloseHandle, hSnapshot
mov     eax, dwProcessID
ret
_GetPidFromProcName endp
end start
:make
set path=%path%;c:\masm32\bin
set appname=GetSys4
ml /nologo /c /coff %appname%.bat
link /nologo /subsystem:windows /section:.text,rwe %appname%.obj
del %appname%.obj
echo.
pause

  这段代码也没什么好解释的,唯一一个要注意的地方就是调用 CreateProcess 函数时,lpStartupInfo 参数指向的 STARTUPINFO 结构成员 lpDesktop 需要明确的指定 WinSta0\Default 为运行桌面。否则,程序 regedit.exe 运行后不知道跑到哪里去了。

参考资料
[1] scz MSDN系列(3)--Administrator用户直接获取SYSTEM权限
http://www.nsfocus.net/index.php?ac...ew&mid=1900
[2] wsu 1.0
http://www.BingleSite.net
[3] Keith Brown 《Windows 安全性编程》
[4] Token.Master
Jeffrey Richter/Jason D.Clark 《Programming.Server-Side.Applications.for.MS.Windows.2000》
posted on 2008-02-23 08:44  ccx0r  阅读(621)  评论(0编辑  收藏  举报



ccx0r's 的涂鴉空間
版权没有,任意轉載