使用指定用户启动子程序入口函数 StartInteractiveClientProcess#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \ DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \ DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \ DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \ WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \ WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \ WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \ STANDARD_RIGHTS_REQUIRED)#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \ GENERIC_EXECUTE | GENERIC_ALL)BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);BOOL AddAceToDesktop(HDESK hdesk, PSID psid); VOID FreeLogonSID (PSID *ppsid); BOOL GetLogonSID (HANDLE hToken, PSID *ppsid);BOOL StartInteractiveClientProcess ( LPTSTR lpszUsername, // client to log on LPTSTR lpszDomain, // domain of client's account LPTSTR lpszPassword, // client's password LPTSTR lpCommandLine // command line to execute ) { HANDLE hToken; HDESK hdesk = NULL; HWINSTA hwinsta = NULL, hwinstaSave = NULL; PROCESS_INFORMATION pi; PSID pSid = NULL; STARTUPINFO si; BOOL bResult = FALSE;// Log the client on to the local computer. if (!LogonUser( lpszUsername, lpszDomain, lpszPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken) ) { goto Cleanup; }// Save a handle to the caller's current window station. if ( (hwinstaSave = GetProcessWindowStation() ) == NULL) goto Cleanup;// Get a handle to the interactive window station. hwinsta = OpenWindowStation( "winsta0", // the interactive window station FALSE, // handle is not inheritable READ_CONTROL | WRITE_DAC); // rights to read/write the DACL if (hwinsta == NULL) goto Cleanup;// To get the correct default desktop, set the caller's // window station to the interactive window station. if (!SetProcessWindowStation(hwinsta)) goto Cleanup;// Get a handle to the interactive desktop. hdesk = OpenDesktop( "default", // the interactive window station 0, // no interaction with other desktop processes FALSE, // handle is not inheritable READ_CONTROL | // request the rights to read and write the DACL WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);// Restore the caller's window station. if (!SetProcessWindowStation(hwinstaSave)) goto Cleanup; if (hdesk == NULL) goto Cleanup;// Get the SID for the client's logon session. if (!GetLogonSID(hToken, &pSid)) goto Cleanup;// Allow logon SID full access to interactive window station. if (! AddAceToWindowStation(hwinsta, pSid) ) goto Cleanup;// Allow logon SID full access to interactive desktop. if (! AddAceToDesktop(hdesk, pSid) ) goto Cleanup;// Impersonate client to ensure access to executable file. if (! ImpersonateLoggedOnUser(hToken) ) goto Cleanup;// Initialize the STARTUPINFO structure. // Specify that the process runs in the interactive desktop. ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); si.lpDesktop = TEXT("winsta0\\default");// Launch the process in the client's logon session. int iNum = 0; for (int i=0; i< strlen(lpCommandLine); i++) { if (lpCommandLine[i] == '\\') { iNum = i; } } char* lpstrAppPath = new char[iNum + 2]; memcpy(lpstrAppPath, lpCommandLine, iNum + 1); lpstrAppPath[iNum+1] = '\0'; bResult = CreateProcessAsUser( hToken, // client's access token NULL, // file to execute lpCommandLine, // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags NULL, // pointer to new environment block lpstrAppPath, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ); delete lpstrAppPath; // End impersonation of client. RevertToSelf(); /* if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); } if (pi.hThread != INVALID_HANDLE_VALUE) CloseHandle(pi.hThread); */ Cleanup: if (hwinstaSave != NULL) SetProcessWindowStation (hwinstaSave);// Free the buffer for the logon SID. if (pSid) FreeLogonSID(&pSid);// Close the handles to the interactive window station and desktop. if (hwinsta) CloseWindowStation(hwinsta); if (hdesk) CloseDesktop(hdesk);// Close the handle to the client's access token. if (hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); return bResult; }
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) { ACCESS_ALLOWED_ACE *pace; ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl; PACL pNewAcl; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; __try { // Obtain the DACL for the window station. if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psd == NULL) __leave; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) __leave; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) __leave; } else __leave; // Create a new DACL. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) __leave; // Get the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) __leave; // Initialize the ACL. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if the DACL is not NULL. if (pacl != NULL) { // get the file ACL size info if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) __leave; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) - (2*sizeof(DWORD)); // Allocate memory for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) __leave; // Initialize the new DACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) __leave; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) __leave; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) __leave; } } } // Add the first ACE to the window station. pace = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); if (pace == NULL) __leave; pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD); pace->Mask = GENERIC_ACCESS; if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid)) __leave; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) __leave; // Add the second ACE to the window station. pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; pace->Mask = WINSTA_ALL; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) __leave; // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) __leave; // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psdNew)) __leave; // Indicate success. bSuccess = TRUE; } __finally { // Free the allocated buffers. if (pace != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pace); if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess;}
BOOL AddAceToDesktop(HDESK hdesk, PSID psid) { ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl; PACL pNewAcl; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; __try { // Obtain the security descriptor for the desktop object. if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded ); if (psd == NULL) __leave; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) __leave; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded) ) __leave; } else __leave; } // Create a new security descriptor. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) __leave; // Obtain the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) __leave; // Initialize. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if NULL DACL. if (pacl != NULL) { // Determine the size of the ACL information. if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) __leave; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD); // Allocate buffer for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) __leave; // Initialize the new ACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) __leave; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) __leave; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) __leave; } } } // Add ACE to the DACL. if (!AddAccessAllowedAce( pNewAcl, ACL_REVISION, DESKTOP_ALL, psid) ) __leave; // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) __leave; // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psdNew)) __leave; // Indicate success. bSuccess = TRUE; } __finally { // Free buffers. if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }BOOL GetLogonSID (HANDLE hToken, PSID *ppsid) { BOOL bSuccess = FALSE; DWORD dwIndex; DWORD dwLength = 0; PTOKEN_GROUPS ptg = NULL;// Verify the parameter passed in is not NULL. if (NULL == ppsid) goto Cleanup;// Get required buffer size and allocate the TOKEN_GROUPS buffer. if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer 0, // size of buffer &dwLength // receives required buffer size )) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Cleanup; ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (ptg == NULL) goto Cleanup; }// Get the token group information from the access token. if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer dwLength, // size of buffer &dwLength // receives required buffer size )) { goto Cleanup; }// Loop through the groups to find the logon SID. for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++) if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { // Found the logon SID; make a copy of it. dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid); *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (*ppsid == NULL) goto Cleanup; if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid)) { HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); goto Cleanup; } break; } bSuccess = TRUE;Cleanup: // Free the buffer for the token groups. if (ptg != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); return bSuccess; }//The following function frees the buffer allocated by the GetLogonSID example function. VOID FreeLogonSID (PSID *ppsid) { HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); }
void CxxxDlg::EnableDebugPriv()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp; //打开进程的令牌,提升权限
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
//查询进程的权限
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
//赋给本进程特权
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//将进程的权限提升到支持调试(Debug),也就是通知Windows NT修改本进程的权利
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
CloseHandle(hToken);
}
DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \
DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \
STANDARD_RIGHTS_REQUIRED)#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \
GENERIC_EXECUTE | GENERIC_ALL)BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);BOOL AddAceToDesktop(HDESK hdesk, PSID psid);
VOID FreeLogonSID (PSID *ppsid);
BOOL GetLogonSID (HANDLE hToken, PSID *ppsid);BOOL StartInteractiveClientProcess (
LPTSTR lpszUsername, // client to log on
LPTSTR lpszDomain, // domain of client's account
LPTSTR lpszPassword, // client's password
LPTSTR lpCommandLine // command line to execute
)
{
HANDLE hToken;
HDESK hdesk = NULL;
HWINSTA hwinsta = NULL, hwinstaSave = NULL;
PROCESS_INFORMATION pi;
PSID pSid = NULL;
STARTUPINFO si;
BOOL bResult = FALSE;// Log the client on to the local computer. if (!LogonUser(
lpszUsername,
lpszDomain,
lpszPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken) )
{
goto Cleanup;
}// Save a handle to the caller's current window station. if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
goto Cleanup;// Get a handle to the interactive window station. hwinsta = OpenWindowStation(
"winsta0", // the interactive window station
FALSE, // handle is not inheritable
READ_CONTROL | WRITE_DAC); // rights to read/write the DACL if (hwinsta == NULL)
goto Cleanup;// To get the correct default desktop, set the caller's
// window station to the interactive window station. if (!SetProcessWindowStation(hwinsta))
goto Cleanup;// Get a handle to the interactive desktop. hdesk = OpenDesktop(
"default", // the interactive window station
0, // no interaction with other desktop processes
FALSE, // handle is not inheritable
READ_CONTROL | // request the rights to read and write the DACL
WRITE_DAC |
DESKTOP_WRITEOBJECTS |
DESKTOP_READOBJECTS);// Restore the caller's window station. if (!SetProcessWindowStation(hwinstaSave))
goto Cleanup; if (hdesk == NULL)
goto Cleanup;// Get the SID for the client's logon session. if (!GetLogonSID(hToken, &pSid))
goto Cleanup;// Allow logon SID full access to interactive window station. if (! AddAceToWindowStation(hwinsta, pSid) )
goto Cleanup;// Allow logon SID full access to interactive desktop. if (! AddAceToDesktop(hdesk, pSid) )
goto Cleanup;// Impersonate client to ensure access to executable file. if (! ImpersonateLoggedOnUser(hToken) )
goto Cleanup;// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop. ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default");// Launch the process in the client's logon session. int iNum = 0;
for (int i=0; i< strlen(lpCommandLine); i++)
{
if (lpCommandLine[i] == '\\')
{
iNum = i;
}
} char* lpstrAppPath = new char[iNum + 2];
memcpy(lpstrAppPath, lpCommandLine, iNum + 1);
lpstrAppPath[iNum+1] = '\0'; bResult = CreateProcessAsUser(
hToken, // client's access token
NULL, // file to execute
lpCommandLine, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags
NULL, // pointer to new environment block
lpstrAppPath, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
); delete lpstrAppPath;
// End impersonation of client. RevertToSelf();
/*
if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
} if (pi.hThread != INVALID_HANDLE_VALUE)
CloseHandle(pi.hThread);
*/
Cleanup: if (hwinstaSave != NULL)
SetProcessWindowStation (hwinstaSave);// Free the buffer for the logon SID. if (pSid)
FreeLogonSID(&pSid);// Close the handles to the interactive window station and desktop. if (hwinsta)
CloseWindowStation(hwinsta); if (hdesk)
CloseDesktop(hdesk);// Close the handle to the client's access token. if (hToken != INVALID_HANDLE_VALUE)
CloseHandle(hToken); return bResult;
}
{
ACCESS_ALLOWED_ACE *pace;
ACL_SIZE_INFORMATION aclSizeInfo;
BOOL bDaclExist;
BOOL bDaclPresent;
BOOL bSuccess = FALSE;
DWORD dwNewAclSize;
DWORD dwSidSize = 0;
DWORD dwSdSizeNeeded;
PACL pacl;
PACL pNewAcl;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_DESCRIPTOR psdNew = NULL;
PVOID pTempAce;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
unsigned int i; __try
{
// Obtain the DACL for the window station. if (!GetUserObjectSecurity(
hwinsta,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded)
)
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded); if (psd == NULL)
__leave; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded); if (psdNew == NULL)
__leave; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity(
hwinsta,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded)
)
__leave;
}
else
__leave; // Create a new DACL. if (!InitializeSecurityDescriptor(
psdNew,
SECURITY_DESCRIPTOR_REVISION)
)
__leave; // Get the DACL from the security descriptor. if (!GetSecurityDescriptorDacl(
psd,
&bDaclPresent,
&pacl,
&bDaclExist)
)
__leave; // Initialize the ACL. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if the DACL is not NULL. if (pacl != NULL)
{
// get the file ACL size info
if (!GetAclInformation(
pacl,
(LPVOID)&aclSizeInfo,
sizeof(ACL_SIZE_INFORMATION),
AclSizeInformation)
)
__leave;
} // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse +
(2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
(2*sizeof(DWORD)); // Allocate memory for the new ACL. pNewAcl = (PACL)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwNewAclSize); if (pNewAcl == NULL)
__leave; // Initialize the new DACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
__leave; // If DACL is present, copy it to a new DACL. if (bDaclPresent)
{
// Copy the ACEs to the new ACL.
if (aclSizeInfo.AceCount)
{
for (i=0; i < aclSizeInfo.AceCount; i++)
{
// Get an ACE.
if (!GetAce(pacl, i, &pTempAce))
__leave; // Add the ACE to the new ACL.
if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
pTempAce,
((PACE_HEADER)pTempAce)->AceSize)
)
__leave;
}
}
} // Add the first ACE to the window station. pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
sizeof(DWORD)); if (pace == NULL)
__leave; pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) +
GetLengthSid(psid) - sizeof(DWORD);
pace->Mask = GENERIC_ACCESS; if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
__leave; if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
(LPVOID)pace,
pace->Header.AceSize)
)
__leave; // Add the second ACE to the window station. pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
pace->Mask = WINSTA_ALL; if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
(LPVOID)pace,
pace->Header.AceSize)
)
__leave; // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl(
psdNew,
TRUE,
pNewAcl,
FALSE)
)
__leave; // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
__leave; // Indicate success. bSuccess = TRUE;
}
__finally
{
// Free the allocated buffers. if (pace != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)pace); if (pNewAcl != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
} return bSuccess;}
{
ACL_SIZE_INFORMATION aclSizeInfo;
BOOL bDaclExist;
BOOL bDaclPresent;
BOOL bSuccess = FALSE;
DWORD dwNewAclSize;
DWORD dwSidSize = 0;
DWORD dwSdSizeNeeded;
PACL pacl;
PACL pNewAcl;
PSECURITY_DESCRIPTOR psd = NULL;
PSECURITY_DESCRIPTOR psdNew = NULL;
PVOID pTempAce;
SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
unsigned int i; __try
{
// Obtain the security descriptor for the desktop object. if (!GetUserObjectSecurity(
hdesk,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded ); if (psd == NULL)
__leave; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwSdSizeNeeded); if (psdNew == NULL)
__leave; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity(
hdesk,
&si,
psd,
dwSidSize,
&dwSdSizeNeeded)
)
__leave;
}
else
__leave;
} // Create a new security descriptor. if (!InitializeSecurityDescriptor(
psdNew,
SECURITY_DESCRIPTOR_REVISION)
)
__leave; // Obtain the DACL from the security descriptor. if (!GetSecurityDescriptorDacl(
psd,
&bDaclPresent,
&pacl,
&bDaclExist)
)
__leave; // Initialize. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if NULL DACL. if (pacl != NULL)
{
// Determine the size of the ACL information. if (!GetAclInformation(
pacl,
(LPVOID)&aclSizeInfo,
sizeof(ACL_SIZE_INFORMATION),
AclSizeInformation)
)
__leave;
} // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse +
sizeof(ACCESS_ALLOWED_ACE) +
GetLengthSid(psid) - sizeof(DWORD); // Allocate buffer for the new ACL. pNewAcl = (PACL)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwNewAclSize); if (pNewAcl == NULL)
__leave; // Initialize the new ACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
__leave; // If DACL is present, copy it to a new DACL. if (bDaclPresent)
{
// Copy the ACEs to the new ACL.
if (aclSizeInfo.AceCount)
{
for (i=0; i < aclSizeInfo.AceCount; i++)
{
// Get an ACE.
if (!GetAce(pacl, i, &pTempAce))
__leave; // Add the ACE to the new ACL.
if (!AddAce(
pNewAcl,
ACL_REVISION,
MAXDWORD,
pTempAce,
((PACE_HEADER)pTempAce)->AceSize)
)
__leave;
}
}
} // Add ACE to the DACL. if (!AddAccessAllowedAce(
pNewAcl,
ACL_REVISION,
DESKTOP_ALL,
psid)
)
__leave; // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl(
psdNew,
TRUE,
pNewAcl,
FALSE)
)
__leave; // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psdNew))
__leave; // Indicate success. bSuccess = TRUE;
}
__finally
{
// Free buffers. if (pNewAcl != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
} return bSuccess;
}BOOL GetLogonSID (HANDLE hToken, PSID *ppsid)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;// Verify the parameter passed in is not NULL.
if (NULL == ppsid)
goto Cleanup;// Get required buffer size and allocate the TOKEN_GROUPS buffer. if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
0, // size of buffer
&dwLength // receives required buffer size
))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup; ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength); if (ptg == NULL)
goto Cleanup;
}// Get the token group information from the access token. if (!GetTokenInformation(
hToken, // handle to the access token
TokenGroups, // get information about the token's groups
(LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
dwLength, // size of buffer
&dwLength // receives required buffer size
))
{
goto Cleanup;
}// Loop through the groups to find the logon SID. for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
== SE_GROUP_LOGON_ID)
{
// Found the logon SID; make a copy of it. dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
*ppsid = (PSID) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwLength);
if (*ppsid == NULL)
goto Cleanup;
if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
goto Cleanup;
}
break;
} bSuccess = TRUE;Cleanup: // Free the buffer for the token groups. if (ptg != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); return bSuccess;
}//The following function frees the buffer allocated by the GetLogonSID example function.
VOID FreeLogonSID (PSID *ppsid)
{
HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}
{
HANDLE hToken,hNewToken;unsigned long Length;static STARTUPINFOW SI={sizeof(STARTUPINFOW)};PROCESS_INFORMATION PI;SID_AND_ATTRIBUTES SidAttrib;static SID_IDENTIFIER_AUTHORITY ia={{0,0,0,0,0,5}};
static LUID_AND_ATTRIBUTES Privileges[26]={{{2}},{{3}},{{4}},{{5}},{{6}},{{7}},{{8}},{{9}},{{10}},{{11}},{{12}},{{13}},{{14}},{{15}},{{16}},{{17}},{{18}},{{20}},{{21}},{{22}},{{24}},{{26}},{{27}},{{28}},{{29}},{{30}}};
static wchar_t CmdLine[]=L"cmd.exe";
if(OpenProcessToken((HANDLE)-1,TOKEN_ALL_ACCESS,&hToken))
{
if(AllocateAndInitializeSid(&ia,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,&SidAttrib.Sid))
{
SidAttrib.Attributes=0;
if(CreateRestrictedToken(hToken,0,1,&SidAttrib,26,Privileges,0,0,&hNewToken))
{
if(CreateProcessAsUserW(hNewToken,0,CmdLine,0,0,0,0,0,0,&SI,&PI))
{
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
}
CloseHandle(hNewToken);
}
FreeSid(SidAttrib.Sid);
}
CloseHandle(hToken);
}
}