我仍未学会那天所...吧 关注:17贴子:341
  • 2回复贴,共1

[转]以系统权限运行程序

只看楼主收藏回复

program sysrun;
uses
Windows, SysUtils, tlhelp32, AccCtrl, AclAPI;
function findprocess(TheProcName: string): DWORD;
var
isOK: Boolean;
ProcessHandle: Thandle;
ProcessStruct: TProcessEntry32;
begin
ProcessHandle := createtoolhelp32snapshot(Th32cs_snapprocess, 0);
processStruct.dwSize := sizeof(ProcessStruct);
isOK := process32first(ProcessHandle, ProcessStruct);
Result := 0;
while isOK do
begin
if Trim(UpperCase(TheProcName)) =
Trim(UpperCase(ProcessStruct.szExeFile)) then
begin
Result := ProcessStruct.th32ProcessID;
CloseHandle(ProcessHandle);
exit;
end;
isOK := process32next(ProcessHandle, ProcessStruct);
end;
CloseHandle(ProcessHandle);
end;
procedure SetPrivilege;
var
TPPrev, TP: TTokenPrivileges;
TokenHandle: THandle;
dwRetLen: DWORD;
lpLuid: TLargeInteger;
begin
OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, TokenHandle);
if (LookupPrivilegeValue(nil, 'SeDebugPrivilege', lpLuid)) then
begin
TP.PrivilegeCount := 1;
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
TP.Privileges[0].Luid := lpLuid;
AdjustTokenPrivileges(TokenHandle, False, TP, SizeOf(TPPrev),
TPPrev, dwRetLen);
end;
CloseHandle(TokenHandle);
end;
/////////////////////////////////////////////////////////////////
function CreateSystemProcess(szProcessName: LPTSTR): BOOL;
var
hProcess: THANDLE;
hToken, hNewToken: THANDLE;
dwPid: DWORD;
pOldDAcl: PACL;
pNewDAcl: PACL;
bDAcl: BOOL;
bDefDAcl: BOOL;
dwRet: DWORD;
pSacl: PACL;
pSidOwner: PSID;
pSidPrimary: PSID;
dwAclSize: DWORD;
dwSaclSize: DWORD;
dwSidOwnLen: DWORD;
dwSidPrimLen: DWORD;
dwSDLen: DWORD;
ea: EXPLICIT_ACCESS;
pOrigSd: PSECURITY_DESCRIPTOR;
pNewSd: PSECURITY_DESCRIPTOR;
si: STARTUPINFO;
pi: PROCESS_INFORMATION;
bError: BOOL;
label Cleanup;
begin
pOldDAcl := nil;
pNewDAcl := nil;
pSacl := nil;
pSidOwner := nil;
pSidPrimary := nil;
dwAclSize := 0;
dwSaclSize := 0;
dwSidOwnLen := 0;
dwSidPrimLen := 0;
pOrigSd := nil;
pNewSd := nil;
SetPrivilege;
//选择 WINLOGON 进程
dwPid := findprocess('WINLOGON.EXE');
if dwPid = High(Cardinal) then
begin
bError := TRUE;
goto Cleanup;
end;
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
if hProcess = 0 then
begin
bError := TRUE;
goto Cleanup;
end;
if not OpenProcessToken(hProcess, READ_CONTROL or WRITE_DAC, hToken)
then
begin
bError := TRUE;
goto Cleanup;
end;
// 设置 ACE 具有所有访问权限
ZeroMemory(@ea, Sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(@ea, 'Everyone', TOKEN_ALL_ACCESS,
GRANT_ACCESS, 0);
if not GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION,
pOrigSd, 0, dwSDLen) then
begin
//第一次调用给出的参数肯定返回这个错误,这样做的目的是为了得到原安全描述符 pOrigSd 的长度
if GetLastError() = ERROR_INSUFFICIENT_BUFFER then
begin



1楼2012-03-19 10:05回复
    pOrigSd := HeapAlloc(GetProcessHeap(), $00000008, dwSDLen);
    if pOrigSd = nil then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    // 再次调用才正确得到安全描述符 pOrigSd
    if not GetKernelObjectSecurity(hToken,
    DACL_SECURITY_INFORMATION, pOrigSd, dwSDLen, dwSDLen) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    end
    else
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    end; //GetKernelObjectSecurity()
    // 得到原安全描述符的访问控制列表 ACL
    if not GetSecurityDescriptorDacl(pOrigSd, bDAcl, pOldDAcl, bDefDAcl)
    then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    // 生成新 ACE 权限的访问控制列表 ACL
    dwRet := SetEntriesInAcl(1, @ea, pOldDAcl, pNewDAcl);
    if dwRet <> ERROR_SUCCESS then
    begin
    pNewDAcl := nil;
    bError := TRUE;
    goto Cleanup;
    end;
    if not MakeAbsoluteSD(pOrigSd, pNewSd, dwSDLen, pOldDAcl^, dwAclSize,
    pSacl^, dwSaclSize, pSidOwner, dwSidOwnLen, pSidPrimary, dwSidPrimLen)
    then
    begin
    {第一次调用给出的参数肯定返回这个错误,这样做的目的是为了创建新的安全描述符 pNewSd 而得到各项的长度}
    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
    begin
    pOldDAcl := HeapAlloc(GetProcessHeap(), $00000008, dwAclSize);
    pSacl := HeapAlloc(GetProcessHeap(), $00000008, dwSaclSize);
    pSidOwner := HeapAlloc(GetProcessHeap(), $00000008,
    dwSidOwnLen);
    pSidPrimary := HeapAlloc(GetProcessHeap(), $00000008,
    dwSidPrimLen);
    pNewSd := HeapAlloc(GetProcessHeap(), $00000008, dwSDLen);
    if (pOldDAcl = nil) or (pSacl = nil) or (pSidOwner = nil) or
    (pSidPrimary = nil) or (pNewSd = nil) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    {再次调用才可以成功创建新的安全描述符 pNewSd
    但新的安全描述符仍然是原访问控制列表 ACL}
    if not MakeAbsoluteSD(pOrigSd, pNewSd, dwSDLen, pOldDAcl^,
    dwAclSize, pSacl^, dwSaclSize, pSidOwner, dwSidOwnLen, pSidPrimary,
    dwSidPrimLen) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    end
    else
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    end;
    {将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的
    安全描述符 pNewSd 中}
    if not SetSecurityDescriptorDacl(pNewSd, bDAcl, pNewDAcl, bDefDAcl)
    then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    // 将新的安全描述符加到 TOKEN 中
    if not SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION,
    pNewSd) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    // 再次打开 WINLOGON 进程的 TOKEN,这时已经具有所有访问权限
    if not OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, hToken) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    // 复制一份具有相同访问权限的 TOKEN
    if not DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, nil,
    SecurityImpersonation, TokenPrimary, hNewToken) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    ZeroMemory(@si, Sizeof(STARTUPINFO));
    si.cb := Sizeof(STARTUPINFO);
    {不虚拟登陆用户的话,创建新进程会提示
    1314 客户没有所需的特权错误}
    ImpersonateLoggedOnUser(hNewToken);
    {我们仅仅是需要建立高权限进程,不用切换用户
    所以也无需设置相关桌面,有了新 TOKEN 足够}
    // 利用具有所有权限的 TOKEN,创建高权限进程
    if not CreateProcessAsUser(hNewToken, nil, szProcessName, nil, nil,
    FALSE, 0, nil, nil, si, pi) then
    begin
    bError := TRUE;
    goto Cleanup;
    end;
    bError := FALSE;
    Cleanup:
    if pOrigSd = nil then HeapFree(GetProcessHeap(), 0, pOrigSd);
    if pNewSd = nil then HeapFree(GetProcessHeap(), 0, pNewSd);
    if pSidPrimary = nil then HeapFree(GetProcessHeap(), 0, pSidPrimary);
    if pSidOwner = nil then HeapFree(GetProcessHeap(), 0, pSidOwner);
    if pSacl = nil then HeapFree(GetProcessHeap(), 0, pSacl);
    if pOldDAcl = nil then HeapFree(GetProcessHeap(), 0, pOldDAcl);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hToken);
    CloseHandle(hNewToken);
    CloseHandle(hProcess);
    if bError then Result := FALSE else Result := True;
    end;
    begin
    CreateSystemProcess(pchar(extractfilepath(paramstr(0)) + aa.exe'));
    end.


    2楼2012-03-19 10:05
    回复
      2025-08-07 19:40:50
      广告
      不感兴趣
      开通SVIP免广告
      噗 竟然精了,自己都没成功过…


      来自掌上百度3楼2012-03-27 12:29
      回复