delphi以system运行程序  
官方Delphi 学习QQ群: 682628230(三千人)
频道

delphi以system运行程序


代码来源于网络 Win7下不可用 Xp下测试无压力

  1. program SysTemRun;  
  2.  
  3. uses  
  4.   Windows,  
  5.   tlhelp32,  
  6.   AccCtrl,  
  7.   AclAPI;  
  8.  
  9.  
  10.  
  11. function UpperCase(const S: string): string;  
  12. var  
  13.   Ch: Char;  
  14.   L: Integer;  
  15.   Source, Dest: PChar;  
  16. begin  
  17.   L := Length(S);  
  18.   SetLength(Result, L);  
  19.   Source := Pointer(S);  
  20.   Dest := Pointer(Result);  
  21.   while L <> 0 do 
  22.   begin  
  23.     Ch := Source^;  
  24.     if (Ch >= 'a') and (Ch <= 'z') then Dec(Ch, 32);  
  25.     Dest^ := Ch;  
  26.     Inc(Source);  
  27.     Inc(Dest);  
  28.     Dec(L);  
  29.   end;  
  30. end;  
  31.  
  32. function LowerCase(const S: string): string;  
  33. var  
  34.   Ch: Char;  
  35.   L: Integer;  
  36.   Source, Dest: PChar;  
  37. begin  
  38.   L := Length(S);  
  39.   SetLength(Result, L);  
  40.   Source := Pointer(S);  
  41.   Dest := Pointer(Result);  
  42.   while L <> 0 do 
  43.   begin  
  44.     Ch := Source^;  
  45.     if (Ch >= 'A') and (Ch <= 'Z') then Inc(Ch, 32);  
  46.     Dest^ := Ch;  
  47.     Inc(Source);  
  48.     Inc(Dest);  
  49.     Dec(L);  
  50.   end;  
  51. end;  
  52.  
  53. function Trim(const S: string): string;  
  54. var  
  55.   I, L: Integer;  
  56. begin  
  57.   L := Length(S);  
  58.   I := 1;  
  59.   while (I <= L) and (S[I] <= ' 'do Inc(I);  
  60.   if I > L then Result := '' else 
  61.   begin  
  62.     while S[L] <= ' ' do Dec(L);  
  63.     Result := Copy(S, I, L - I + 1);  
  64.   end;  
  65. end;  
  66.  
  67. function findprocess(TheProcName: string): DWORD;  
  68. var  
  69. isOK: Boolean;  
  70. ProcessHandle: Thandle;  
  71. ProcessStruct: TProcessEntry32;  
  72. begin  
  73. ProcessHandle := createtoolhelp32snapshot(Th32cs_snapprocess, 0);  
  74. processStruct.dwSize := sizeof(ProcessStruct);  
  75. isOK := process32first(ProcessHandle, ProcessStruct);  
  76. Result := 0;  
  77. while isOK do 
  78. begin  
  79.     if Trim(UpperCase(TheProcName)) = Trim(UpperCase(ProcessStruct.szExeFile)) then  
  80.     begin  
  81.       Result := ProcessStruct.th32ProcessID;  
  82.       CloseHandle(ProcessHandle);  
  83.       exit;  
  84.     end;  
  85.     isOK := process32next(ProcessHandle, ProcessStruct);  
  86. end;  
  87. CloseHandle(ProcessHandle);  
  88. end;  
  89.  
  90. procedure SetPrivilege;  
  91. var  
  92. TPPrev, TP: TTokenPrivileges;  
  93. TokenHandle: THandle;  
  94. dwRetLen: DWORD;  
  95. lpLuid: TLargeInteger;  
  96. begin  
  97. OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, TokenHandle);  
  98. if (LookupPrivilegeValue(nil, 'SeDebugPrivilege', lpLuid)) then  
  99. begin  
  100.     TP.PrivilegeCount := 1;  
  101.     TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;  
  102.     TP.Privileges[0].Luid := lpLuid;  
  103.     AdjustTokenPrivileges(TokenHandle, False, TP, SizeOf(TPPrev), TPPrev, dwRetLen);  
  104. end;  
  105. CloseHandle(TokenHandle);  
  106. end;  
  107.  
  108. /////////////////////////////////////////////////////////////////  
  109.  
  110. function CreateSystemProcess(szProcessName: LPTSTR): BOOL;  
  111. var  
  112. hProcess: THANDLE;  
  113. hToken, hNewToken: THANDLE;  
  114. dwPid: DWORD;  
  115. pOldDAcl: PACL;  
  116. pNewDAcl: PACL;  
  117. bDAcl: BOOL;  
  118. bDefDAcl: BOOL;  
  119. dwRet: DWORD;  
  120. pSacl: PACL;  
  121. pSidOwner: PSID;  
  122. pSidPrimary: PSID;  
  123. dwAclSize: DWORD;  
  124. dwSaclSize: DWORD;  
  125. dwSidOwnLen: DWORD;  
  126. dwSidPrimLen: DWORD;  
  127. dwSDLen: DWORD;  
  128. ea: EXPLICIT_ACCESS;  
  129. pOrigSd: PSECURITY_DESCRIPTOR;  
  130. pNewSd: PSECURITY_DESCRIPTOR;  
  131. si: STARTUPINFO;  
  132. pi: PROCESS_INFORMATION;  
  133. bError: BOOL;  
  134. label Cleanup;  
  135. begin  
  136. pOldDAcl := nil;  
  137. pNewDAcl := nil;  
  138. pSacl := nil;  
  139. pSidOwner := nil;  
  140. pSidPrimary := nil;  
  141. dwAclSize := 0;  
  142. dwSaclSize := 0;  
  143. dwSidOwnLen := 0;  
  144. dwSidPrimLen := 0;  
  145. pOrigSd := nil;  
  146. pNewSd := nil;  
  147. SetPrivilege;  
  148. //选择 WINLOGON 进程  
  149. dwPid := findprocess('WINLOGON.EXE');  
  150. if dwPid = High(Cardinal) then  
  151. begin  
  152.     bError := TRUE;  
  153.     goto Cleanup;  
  154. end;  
  155. hProcess := OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);  
  156. if hProcess = 0 then  
  157. begin  
  158.     bError := TRUE;  
  159.     goto Cleanup;  
  160. end;  
  161. if not OpenProcessToken(hProcess, READ_CONTROL or WRITE_DAC, hToken) then  
  162. begin  
  163.     bError := TRUE;  
  164.     goto Cleanup;  
  165. end;  
  166. // 设置 ACE 具有所有访问权限  
  167. ZeroMemory(@ea, Sizeof(EXPLICIT_ACCESS));  
  168. BuildExplicitAccessWithName(@ea, 'Everyone', TOKEN_ALL_ACCESS, GRANT_ACCESS, 0);  
  169. if not GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pOrigSd, 0, dwSDLen) then  
  170. begin  
  171.     //第一次调用给出的参数肯定返回这个错误,这样做的目的是为了得到原安全描述符 pOrigSd 的长度  
  172.     if GetLastError() = ERROR_INSUFFICIENT_BUFFER then  
  173.     begin  
  174.       pOrigSd := HeapAlloc(GetProcessHeap(), $00000008, dwSDLen);  
  175.       if pOrigSd = nil then  
  176.       begin  
  177.         bError := TRUE;  
  178.         goto Cleanup;  
  179.       end;  
  180.       // 再次调用才正确得到安全描述符 pOrigSd  
  181.       if not GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pOrigSd, dwSDLen, dwSDLen) then  
  182.       begin  
  183.         bError := TRUE;  
  184.         goto Cleanup;  
  185.       end;  
  186.     end  
  187.     else 
  188.     begin  
  189.       bError := TRUE;  
  190.       goto Cleanup;  
  191.     end;  
  192. end; //GetKernelObjectSecurity()  
  193. // 得到原安全描述符的访问控制列表 ACL  
  194. if not GetSecurityDescriptorDacl(pOrigSd, bDAcl, pOldDAcl, bDefDAcl) then  
  195. begin  
  196.     bError := TRUE;  
  197.     goto Cleanup;  
  198. end;  
  199. // 生成新 ACE 权限的访问控制列表 ACL  
  200. dwRet := SetEntriesInAcl(1, @ea, pOldDAcl, pNewDAcl);  
  201. if dwRet <> ERROR_SUCCESS then  
  202. begin  
  203.     pNewDAcl := nil;  
  204.     bError := TRUE;  
  205.     goto Cleanup;  
  206. end;  
  207. if not MakeAbsoluteSD(pOrigSd, pNewSd, dwSDLen, pOldDAcl^, dwAclSize, pSacl^, dwSaclSize, pSidOwner, dwSidOwnLen, pSidPrimary, dwSidPrimLen) then  
  208. begin  
  209.     {第一次调用给出的参数肯定返回这个错误,这样做的目的是为了创建新的安全描述符 pNewSd 而得到各项的长度}  
  210.     if GetLastError = ERROR_INSUFFICIENT_BUFFER then  
  211.     begin  
  212.       pOldDAcl := HeapAlloc(GetProcessHeap(), $00000008, dwAclSize);  
  213.       pSacl := HeapAlloc(GetProcessHeap(), $00000008, dwSaclSize);  
  214.       pSidOwner := HeapAlloc(GetProcessHeap(), $00000008, dwSidOwnLen);  
  215.       pSidPrimary := HeapAlloc(GetProcessHeap(), $00000008, dwSidPrimLen);  
  216.       pNewSd := HeapAlloc(GetProcessHeap(), $00000008, dwSDLen);  
  217.       if (pOldDAcl = nil) or (pSacl = nil) or (pSidOwner = nil) or (pSidPrimary = nil) or (pNewSd = nil) then  
  218.       begin  
  219.         bError := TRUE;  
  220.         goto Cleanup;  
  221.       end;  
  222.       {再次调用才可以成功创建新的安全描述符 pNewSd  
  223.       但新的安全描述符仍然是原访问控制列表 ACL}  
  224.       if not MakeAbsoluteSD(pOrigSd, pNewSd, dwSDLen, pOldDAcl^, dwAclSize, pSacl^, dwSaclSize, pSidOwner, dwSidOwnLen, pSidPrimary, dwSidPrimLen) then  
  225.       begin  
  226.         bError := TRUE;  
  227.         goto Cleanup;  
  228.       end;  
  229.     end  
  230.     else 
  231.     begin  
  232.       bError := TRUE;  
  233.       goto Cleanup;  
  234.     end;  
  235. end;  
  236. {将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的  
  237. 安全描述符 pNewSd 中}  
  238. if not SetSecurityDescriptorDacl(pNewSd, bDAcl, pNewDAcl, bDefDAcl) then  
  239. begin  
  240.     bError := TRUE;  
  241.     goto Cleanup;  
  242. end;  
  243. // 将新的安全描述符加到 TOKEN 中  
  244. if not SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pNewSd) then  
  245. begin  
  246.     bError := TRUE;  
  247.     goto Cleanup;  
  248. end;  
  249. // 再次打开 WINLOGON 进程的 TOKEN,这时已经具有所有访问权限  
  250. if not OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, hToken) then  
  251. begin  
  252.     bError := TRUE;  
  253.     goto Cleanup;  
  254. end;  
  255. // 复制一份具有相同访问权限的 TOKEN  
  256. if not DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, nil, SecurityImpersonation, TokenPrimary, hNewToken) then  
  257. begin  
  258.     bError := TRUE;  
  259.     goto Cleanup;  
  260. end;  
  261. ZeroMemory(@si, Sizeof(STARTUPINFO));  
  262. si.cb := Sizeof(STARTUPINFO);  
  263. {不虚拟登陆用户的话,创建新进程会提示  
  264. 1314 客户没有所需的特权错误}  
  265. ImpersonateLoggedOnUser(hNewToken);  
  266. {我们仅仅是需要建立高权限进程,不用切换用户  
  267. 所以也无需设置相关桌面,有了新 TOKEN 足够}  
  268. // 利用具有所有权限的 TOKEN,创建高权限进程  
  269. if not CreateProcessAsUser(hNewToken, nil, szProcessName, nil, nil, FALSE, 0, nil, nil, si, pi) then  
  270. begin  
  271.     bError := TRUE;  
  272.     goto Cleanup;  
  273. end;  
  274. bError := FALSE;  
  275. Cleanup:  
  276. if pOrigSd = nil then HeapFree(GetProcessHeap(), 0, pOrigSd);  
  277. if pNewSd = nil then HeapFree(GetProcessHeap(), 0, pNewSd);  
  278. if pSidPrimary = nil then HeapFree(GetProcessHeap(), 0, pSidPrimary);  
  279. if pSidOwner = nil then HeapFree(GetProcessHeap(), 0, pSidOwner);  
  280. if pSacl = nil then HeapFree(GetProcessHeap(), 0, pSacl);  
  281. if pOldDAcl = nil then HeapFree(GetProcessHeap(), 0, pOldDAcl);  
  282. CloseHandle(pi.hProcess);  
  283. CloseHandle(pi.hThread);  
  284. CloseHandle(hToken);  
  285. CloseHandle(hNewToken);  
  286. CloseHandle(hProcess);  
  287. if bError then Result := FALSE else Result := True;  
  288.  
  289. end;  
  290.  
  291. var  
  292.   FileDir:String;  
  293. begin  
  294.   //CreateSystemProcess('NOTEPAD.EXE');  
  295.   FileDir := ParamStr(1);  
  296.   if FileDir <> '' then  
  297.   begin  
  298.      CreateSystemProcess(PAnsiChar(FileDir));  
  299.   end;  
  300. end.  

推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.10411381721497 seconds