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, );
processStruct.dwSize := sizeof(ProcessStruct);
isOK := process32first(ProcessHandle, ProcessStruct);
Result := ;
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 := ;
TP.Privileges[].Attributes := SE_PRIVILEGE_ENABLED;
TP.Privileges[].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 := ;
dwSaclSize := ;
dwSidOwnLen := ;
dwSidPrimLen := ;
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 = 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, );
if not GetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pOrigSd, , dwSDLen) then
begin
//第一次调用给出的参数肯定返回这个错误,这样做的目的是为了得到原安全描述符 pOrigSd 的长度
if GetLastError() = ERROR_INSUFFICIENT_BUFFER then
begin
pOrigSd := HeapAlloc(GetProcessHeap(), $, 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(, @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(), $, dwAclSize);
pSacl := HeapAlloc(GetProcessHeap(), $, dwSaclSize);
pSidOwner := HeapAlloc(GetProcessHeap(), $, dwSidOwnLen);
pSidPrimary := HeapAlloc(GetProcessHeap(), $, dwSidPrimLen);
pNewSd := HeapAlloc(GetProcessHeap(), $, 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, , nil, nil, si, pi) then
begin
bError := TRUE;
goto Cleanup;
end;
bError := FALSE;
Cleanup:
if pOrigSd = nil then HeapFree(GetProcessHeap(), , pOrigSd);
if pNewSd = nil then HeapFree(GetProcessHeap(), , pNewSd);
if pSidPrimary = nil then HeapFree(GetProcessHeap(), , pSidPrimary);
if pSidOwner = nil then HeapFree(GetProcessHeap(), , pSidOwner);
if pSacl = nil then HeapFree(GetProcessHeap(), , pSacl);
if pOldDAcl = nil then HeapFree(GetProcessHeap(), , 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()) + aa.exe'));
end.

最新文章

  1. Ubuntu学习总结-12 linux 平台及 windows 平台 mysql 重启方法
  2. FusionCharts饼图的图例属性
  3. 基于内存,redis,mysql的高速游戏数据服务器设计架构
  4. ajax回调打开新窗体防止浏览器拦截有效方法
  5. System-Defined Device Setup Classes Available to Vendors
  6. -_-#【Cookie】使用无 cookies 的域
  7. 【开发工具 - Git】之Git常用命令汇总
  8. Appium移动自动化测试(一)--安装Appium(转)
  9. BeanstalkClient学习
  10. Hadoop之HDFS原理及文件上传下载源码分析(下)
  11. 1. 生成三行文本,过滤文本,cp不覆盖,find查找文件,sed打印行,查看系统信息,磁盘分区
  12. HTML(二)HTML元素(整体结构,块级元素,内联元素,结构元素,交互元素,元素嵌套规则)
  13. spring cloud
  14. LeetCode——162. Find Peak Element
  15. java面试题整理(3)
  16. springMVC学习 六 跳转方式
  17. Ubuntu 中启用 root 帐号
  18. 项目:Android平台txt阅读软件
  19. JS中深拷贝数组、对象、对象数组方法
  20. 第83天:jQuery中操作form表单

热门文章

  1. 前端开发本地存储之localStorage和sessionStorage
  2. 【HDOJ6578】Blank(DP)
  3. 【SPOJ1811】Longest Common Substring(后缀自动机)
  4. this.$nextTick 与window.setTimeout
  5. Codeforces 510C (拓扑排序)
  6. linux中yum install 命令无效
  7. 在Windows及Linux下获取毫秒级运行时间的方法
  8. chromedriver安装报错
  9. 怎么追加byte内容
  10. vue (UI)