以系统最高权限运行软件
生活随笔
收集整理的這篇文章主要介紹了
以系统最高权限运行软件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
///說明:VC6編譯通過
//文件名:UAC.h
//調用:UAC(進程名,可執行文件路徑);
#pragma once #include <windows.h> #include <Aclapi.h> #include <TLHelp32.h>typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdFunc)(); typedef BOOL (WINAPI *ProcessIdToSessionIdFunc)(DWORD dwProcessId,DWORD* pSessionId); typedef BOOL (WINAPI *WTSQueryUserTokenFunc)(ULONG SessionId,PHANDLE phToken); typedef BOOL (WINAPI *CreateEnvironmentBlockFunc)(LPVOID *lpEnvironment,HANDLE hToken,BOOL bInherit);WTSGetActiveConsoleSessionIdFunc WTSGetActiveConsoleSessionId=NULL; ProcessIdToSessionIdFunc ProcessIdToSessionId=NULL; WTSQueryUserTokenFunc WTSQueryUserToken=NULL; CreateEnvironmentBlockFunc CreateEnvironmentBlock=NULL;//獲取所需函數地址 void GetFunc() {HMODULE hKernel32=LoadLibrary("Kernel32.dll");HMODULE hWtsapi32=LoadLibrary("Wtsapi32.dll");HMODULE hUserenv=LoadLibrary("userenv.dll");if (hKernel32 && hWtsapi32 && hUserenv){WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdFunc)GetProcAddress(hKernel32,"WTSGetActiveConsoleSessionId");ProcessIdToSessionId = (ProcessIdToSessionIdFunc)GetProcAddress(hKernel32,"ProcessIdToSessionId");WTSQueryUserToken = (WTSQueryUserTokenFunc)GetProcAddress(hWtsapi32,"WTSQueryUserToken");CreateEnvironmentBlock=(CreateEnvironmentBlockFunc)GetProcAddress(hUserenv,"CreateEnvironmentBlock");} }//開啟本線程的SeDeDebug權限 bool EnableDebugPrivilege() {HANDLE hToken;TOKEN_PRIVILEGES tp;if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))return false;if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid))return false;tp.PrivilegeCount=1;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))return false;return true; }//主函數 BOOL UAC(char *ProcessName,char *ExecuteFilePath) {DWORD dwSessionId=0,TmpSessionId=0,PID=0,dwCreateFlags,dwSdLen,dwRet,dwAclSize=0,dwSaclSize=0,dwSidOwnLen=0,dwSidPrimLen=0;HANDLE hSnap=NULL,hUserToken=NULL,hNewUserToken=NULL,hToken=NULL,hProcess;PROCESSENTRY32 pe={0x00};BOOL Flag=false,bRet=false,bDAcl,bDefDAcl;TOKEN_PRIVILEGES tp;LPVOID lpEnv;STARTUPINFO si;PROCESS_INFORMATION pi;EXPLICIT_ACCESS ea;PSECURITY_DESCRIPTOR pOrigSd=NULL,pNewSd=NULL;PACL pOldDAcl=NULL,pNewDAcl=NULL,pSacl=NULL;PSID pSidOwner=NULL,pSidPrimary=NULL;//獲取所需函數 GetFunc();//開啟本線程權限 EnableDebugPrivilege();//Baby,come on!dwSessionId=WTSGetActiveConsoleSessionId();//查找進程,獲取PIDhSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);pe.dwSize=sizeof(pe);Flag=Process32First(hSnap,&pe);while (Flag){if (strcmp(strlwr(pe.szExeFile),strlwr(ProcessName))==0){ProcessIdToSessionId(pe.th32ProcessID,&TmpSessionId);if (TmpSessionId==dwSessionId){PID=pe.th32ProcessID;break;}}Flag=Process32Next(hSnap,&pe);}//獲取用戶令牌WTSQueryUserToken(dwSessionId,&hUserToken);hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID);if (!hProcess)return FALSE;if (!OpenProcessToken(hProcess,READ_CONTROL|WRITE_DAC,&hToken))return FALSE;//設置ACE具有所有訪問權限ZeroMemory(&ea,sizeof(EXPLICIT_ACCESS));BuildExplicitAccessWithName(&ea,"Everyone",TOKEN_ALL_ACCESS,GRANT_ACCESS,0);//第一次調用肯定返回這個錯誤,這是為了得到原安全描述符 pOrigSd 的長度if (!GetKernelObjectSecurity(hToken,DACL_SECURITY_INFORMATION,pOrigSd,0,&dwSdLen)){if (GetLastError()==ERROR_INSUFFICIENT_BUFFER){pOrigSd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdLen);if (pOrigSd==NULL)return FALSE;}}//第二次調用得到安全描述符 pOrigSdif (!GetKernelObjectSecurity(hToken,DACL_SECURITY_INFORMATION,pOrigSd,dwSdLen,&dwSdLen))return FALSE;//得到原安全描述符的訪問控制列表 ACLif (!GetSecurityDescriptorDacl(pOrigSd,&bDAcl,&pOldDAcl,&bDefDAcl))return FALSE;// 生成新 ACE 權限的訪問控制列表 ACLdwRet=SetEntriesInAcl(1,&ea,pOldDAcl,&pNewDAcl);if (dwRet!=ERROR_SUCCESS)return FALSE;//第一次調用肯定返回錯誤,為了創建新的安全描述符 pNewSd 而得到各項的長度if (!MakeAbsoluteSD(pOrigSd,pNewSd,&dwSdLen,pOldDAcl,&dwAclSize,pSacl,&dwSaclSize,pSidOwner,&dwSidOwnLen,pSidPrimary,&dwSidPrimLen)){if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){pOldDAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwAclSize);pSacl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSaclSize);pSidOwner = (PSID)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSidOwnLen);pSidPrimary=(PSID)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSidPrimLen);pNewSd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdLen);if (pOldDAcl==NULL || pSacl==NULL || pSidOwner==NULL || pSidPrimary==NULL || pNewSd==NULL)return FALSE;}}//再次調用才可以成功創建新的安全描述符 pNewSdif (!MakeAbsoluteSD(pOrigSd,pNewSd,&dwSdLen,pOldDAcl,&dwAclSize,pSacl,&dwSaclSize,pSidOwner,&dwSidOwnLen,pSidPrimary,&dwSidPrimLen))return FALSE;//將具有所有訪問權限的訪問控制列表 pNewDAcl 加入到新的 安全描述符 pNewSd 中if (!SetSecurityDescriptorDacl(pNewSd,bDAcl,pNewDAcl,bDefDAcl))return FALSE;//將新的安全描述符加到 TOKEN 中if (!SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, pNewSd))return FALSE;//再次打開進程的 TOKEN,這時已經具有所有訪問權限if (!OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken))return FALSE;//復制令牌if (!DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hNewUserToken))return FALSE;//結束進程,危險,虛擬機測試//TerminateProcess(hProcess,0);//不虛擬登陸用戶的話,創建新進程會提示 ImpersonateLoggedOnUser(hNewUserToken);//創建環境if (CreateEnvironmentBlock(&lpEnv,hNewUserToken,TRUE))dwCreateFlags=NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT;elselpEnv=NULL;ZeroMemory(&si,sizeof(si));ZeroMemory(&pi,sizeof(pi));si.cb=sizeof(si);si.lpDesktop="winsta0\default";bRet=CreateProcessAsUser(hNewUserToken,ExecuteFilePath,NULL,NULL,NULL,FALSE,dwCreateFlags,lpEnv,NULL,&si,&pi);//byeHeapFree(GetProcessHeap(),0,pOrigSd);HeapFree(GetProcessHeap(),0,pNewSd);HeapFree(GetProcessHeap(),0,pSidOwner);HeapFree(GetProcessHeap(),0,pSidPrimary);HeapFree(GetProcessHeap(),0,pSacl);HeapFree(GetProcessHeap(),0,pOldDAcl);CloseHandle(hSnap);CloseHandle(hProcess);CloseHandle(hToken);CloseHandle(hUserToken);CloseHandle(hNewUserToken); }
?
另注:亦可以用來結束系統進程。
轉載于:https://www.cnblogs.com/littleevil/archive/2012/05/22/2513747.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的以系统最高权限运行软件的全部內容,希望文章能夠幫你解決所遇到的問題。