本地系统pipe理员的CreateProcessAsUser不应用Windows样式

我在使用本地系统pipe理员的Windows API CreateProcessAsUser的应用程序中遇到问题,以便以不同的用户身份运行应用程序。 到目前为止一切正常,但Windows窗口和框架样式不应用某种方式。 该窗口总是看起来像一个巨大的框架的Windows 2000窗口。 我还附上了一些截图

破碎的风格窗口

我还写了一些示例代码,说明如何在C ++中完成所有的魔术,而不需要考虑句柄和东西。

只要确保你有本地的一些用户“testing”与密码“testing”设置,并尝试运行公布的源代码作为本地系统pipe理员。 如果您尝试执行代码,其他用户将导致错误代码1413。

该问题主要发生在VirtualBox中的Windows 7虚拟机,某些Windows 7系统和所有Windows 8.1系统上。 很奇怪。 任何人都可以帮我解决这个问题吗? 谢谢!

#include <iostream> #include <Windows.h> #include <UserEnv.h> #include <WinWlx.h> int AddAceToWindowStation( HWINSTA hwinsta, PSID psid ) { DWORD lengthNeeded; SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION; if( !GetUserObjectSecurity( hwinsta, &secInfo, NULL, NULL, &lengthNeeded ) ) { if ( GetLastError() != 122 ) { std::cout << "GetUserObjectSecurity1 error: " << GetLastError() << std::endl; return 0; } } PSECURITY_DESCRIPTOR pSecDescriptor = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lengthNeeded ); if ( pSecDescriptor == NULL ) { std::cout << "Allocating memory for pSecDescriptor failed: " << GetLastError() << std::endl; return 0; } PSECURITY_DESCRIPTOR pSecDescriptorNew = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lengthNeeded ); if ( pSecDescriptorNew == NULL ) { std::cout << "Allocating memory for pSecDescriptorNew failed: " << GetLastError() << std::endl; return 0; } if ( !GetUserObjectSecurity( hwinsta, &secInfo, pSecDescriptor, lengthNeeded, &lengthNeeded ) ) { std::cout << "GetUserObjectSecurity2 error: " << GetLastError() << std::endl; return 0; } if ( !InitializeSecurityDescriptor( pSecDescriptorNew, SECURITY_DESCRIPTOR_REVISION ) ) { std::cout << "InitializeSecurityDescriptor error: " << GetLastError() << std::endl; return 0; } BOOL DaclPresent; PACL pOldDacl; BOOL DaclDefaulted; if ( !GetSecurityDescriptorDacl( pSecDescriptor, &DaclPresent, &pOldDacl, &DaclDefaulted ) ) { std::cout << "GetSecurityDescriptorDacl error: " << GetLastError() << std::endl; return 0; } // Get size information for DACL ACL_SIZE_INFORMATION AclInfo; AclInfo.AceCount = 0; // Assume NULL DACL. AclInfo.AclBytesFree = 0; AclInfo.AclBytesInUse = sizeof( ACL ); if ( pOldDacl == NULL ) DaclPresent = FALSE; // If not NULL DACL, gather size information from DACL. if ( DaclPresent ) { if ( !GetAclInformation( pOldDacl, &AclInfo, sizeof( ACL_SIZE_INFORMATION ), AclSizeInformation ) ) { std::cout << "GetAclInformation error: " << GetLastError() << std::endl; return 0; } } DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof( ACCESS_ALLOWED_ACE ) + sizeof( ACL ) + sizeof( ACL ) + sizeof( ACCESS_ALLOWED_ACE ) + sizeof( ACL ) + sizeof( ACL ); PACL pNewACL = ( PACL ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL ); if ( !InitializeAcl( pNewACL, cbNewACL, ACL_REVISION ) ) { std::cout << "InitializeAcl error: " << GetLastError() << std::endl; return 0; } LPVOID pTempAce = NULL; // Copy old Ace to new DACL if ( DaclPresent && AclInfo.AceCount ) { std::cout << "AclInfo.AceCount:" << AclInfo.AceCount << std::endl; for ( int i = 0; i < AclInfo.AceCount; ++i ) { if ( !GetAce( pOldDacl, i, &pTempAce ) ) { std::cout << "GetAce[" << i << "] error: " << GetLastError() << std::endl; return 0; } if ( !AddAce( pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ( ( PACE_HEADER ) pTempAce )->AceSize ) ) { std::cout << "AddAce[" << i << "] error: " << GetLastError() << std::endl; return 0; } } } if ( !AddAccessAllowedAceEx( pNewACL, ACL_REVISION, CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL, psid ) ) { std::cout << "AddAccessAllowedAceEx1 error: " << GetLastError() << std::endl; return 0; } if ( !AddAccessAllowedAceEx( pNewACL, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | STANDARD_RIGHTS_REQUIRED, psid ) ) { std::cout << "AddAccessAllowedAceEx2 error: " << GetLastError() << std::endl; return 0; } if ( !SetSecurityDescriptorDacl( pSecDescriptorNew, TRUE, pNewACL, FALSE ) ) { std::cout << "SetSecurityDescriptorDacl error: " << GetLastError() << std::endl; return 0; } if ( !SetUserObjectSecurity( hwinsta, &secInfo, pSecDescriptorNew ) ) { std::cout << "SetUserObjectSecurity error: " << GetLastError() << std::endl; return 0; } return 1; } int AddAceToDesktop( HDESK hdesk, PSID psid ) { DWORD lengthNeeded; SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION; if ( !GetUserObjectSecurity( hdesk, &secInfo, NULL, NULL, &lengthNeeded ) ) { if ( GetLastError() != 122 ) { std::cout << "GetUserObjectSecurity1 error: " << GetLastError() << std::endl; return 0; } } PSECURITY_DESCRIPTOR pSecDescriptor = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lengthNeeded ); if ( pSecDescriptor == NULL ) { std::cout << "Allocating memory for pSecDescriptor failed: " << GetLastError() << std::endl; return 0; } PSECURITY_DESCRIPTOR pSecDescriptorNew = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lengthNeeded ); if ( pSecDescriptorNew == NULL ) { std::cout << "Allocating memory for pSecDescriptorNew failed: " << GetLastError() << std::endl; return 0; } if ( !GetUserObjectSecurity( hdesk, &secInfo, pSecDescriptor, lengthNeeded, &lengthNeeded ) ) { std::cout << "GetUserObjectSecurity2 error: " << GetLastError() << std::endl; return 0; } if ( !InitializeSecurityDescriptor( pSecDescriptorNew, SECURITY_DESCRIPTOR_REVISION ) ) { std::cout << "InitializeSecurityDescriptor error: " << GetLastError() << std::endl; return 0; } BOOL DaclPresent; PACL pOldDacl; BOOL DaclDefaulted; if ( !GetSecurityDescriptorDacl( pSecDescriptor, &DaclPresent, &pOldDacl, &DaclDefaulted ) ) { std::cout << "GetSecurityDescriptorDacl error: " << GetLastError() << std::endl; return 0; } // Get size information for DACL ACL_SIZE_INFORMATION AclInfo; AclInfo.AceCount = 0; // Assume NULL DACL. AclInfo.AclBytesFree = 0; AclInfo.AclBytesInUse = sizeof( ACL ); if ( pOldDacl == NULL ) DaclPresent = FALSE; // If not NULL DACL, gather size information from DACL. if ( DaclPresent ) { if ( !GetAclInformation( pOldDacl, &AclInfo, sizeof( ACL_SIZE_INFORMATION ), AclSizeInformation ) ) { std::cout << "GetAclInformation error: " << GetLastError() << std::endl; return 0; } } DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof( ACCESS_ALLOWED_ACE ) + sizeof( ACL ) + sizeof( ACL ); PACL pNewACL = ( PACL ) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbNewACL ); if ( !InitializeAcl( pNewACL, cbNewACL, ACL_REVISION ) ) { std::cout << "InitializeAcl error: " << GetLastError() << std::endl; return 0; } LPVOID pTempAce = NULL; // Copy old Ace to new DACL if ( DaclPresent && AclInfo.AceCount ) { std::cout << "AclInfo.AceCount:" << AclInfo.AceCount << std::endl; for ( int i = 0; i < AclInfo.AceCount; ++i ) { if ( !GetAce( pOldDacl, i, &pTempAce ) ) { std::cout << "GetAce[" << i << "] error: " << GetLastError() << std::endl; return 0; } if ( !AddAce( pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ( ( PACE_HEADER ) pTempAce )->AceSize ) ) { std::cout << "AddAce[" << i << "] error: " << GetLastError() << std::endl; return 0; } } } if ( !AddAccessAllowedAce( pNewACL, ACL_REVISION, DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED, psid ) ) { std::cout << "AddAccessAllowedAce error: " << GetLastError() << std::endl; return 0; } if ( !SetSecurityDescriptorDacl( pSecDescriptorNew, TRUE, pNewACL, FALSE ) ) { std::cout << "SetSecurityDescriptorDacl error: " << GetLastError() << std::endl; return 0; } if ( !SetUserObjectSecurity( hdesk, &secInfo, pSecDescriptorNew ) ) { std::cout << "SetUserObjectSecurity error: " << GetLastError() << std::endl; return 0; } return 1; } int AddAceToBaseNameObjectsDirectory( PSID psid, TOKEN_INFORMATION_CLASS tClass ) { return 0; } int main( int argc, TCHAR *argv[] ) { HANDLE userToken; if ( !LogonUser( L"test", L"", L"test", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &userToken ) ) { std::cout << "LogonUser error: " << GetLastError() << std::endl; return -1; } HANDLE token; if ( !DuplicateTokenEx( userToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &token ) ) { std::cout << "DuplicateTokenEx error: " << GetLastError() << std::endl; return -1; } PROFILEINFO profileInfo; profileInfo.lpUserName = L"test"; profileInfo.dwFlags = NULL; profileInfo.lpProfilePath = L"C:\\Users\\test"; LoadUserProfile( token, &profileInfo ); LUID tcb_privilege_flag; if ( !LookupPrivilegeValue( NULL, SE_SECURITY_NAME, &tcb_privilege_flag ) ) { std::cout << "LookupPrivilegeValue error: " << GetLastError() << std::endl; return -1; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = tcb_privilege_flag; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if ( !AdjustTokenPrivileges( token, FALSE, &tp, sizeof( TOKEN_PRIVILEGES ), ( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL ) ) { std::cout << "AdjustTokenPrivileges error: " << GetLastError() << std::endl; return -1; } HWINSTA hwinstasave = GetProcessWindowStation(); HWINSTA hwinsta = OpenWindowStation( L"winsta0", FALSE, READ_CONTROL | WRITE_DAC ); HDESK hdesk = OpenDesktop( L"default", NULL, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS ); DWORD token_group_size; if ( !GetTokenInformation( token, TokenGroups, NULL, 0, &token_group_size ) ) { if ( GetLastError() != 122 ) { std::cout << "GetTokenInformation1 error: " << GetLastError() << std::endl; return -1; } } PTOKEN_GROUPS pTokenGroup = ( PTOKEN_GROUPS ) new BYTE[token_group_size]; memset( pTokenGroup, 0, token_group_size ); if ( !GetTokenInformation( token, TokenGroups, pTokenGroup, token_group_size, &token_group_size ) ) { std::cout << "GetTokenInformation2 error: " << GetLastError() << std::endl; return -1; } PSID pSid = NULL; for ( int i = 0; i < pTokenGroup->GroupCount; ++i ) { if ( ( pTokenGroup->Groups[i].Attributes & SE_GROUP_LOGON_ID ) == SE_GROUP_LOGON_ID ) { pSid = pTokenGroup->Groups[i].Sid; } } if ( pSid == NULL ) { std::cout << "Unable to get logonSID error! No entry found!!!" << std::endl; return -1; } if ( !AddAceToWindowStation( hwinsta, pSid ) ) { std::cout << "AddAceToWindowStation error: " << GetLastError() << std::endl; return -1; } if ( !AddAceToDesktop( hdesk, pSid ) ) { std::cout << "AddAceToDesktop error: " << GetLastError() << std::endl; return -1; } //if ( !AddAceToBaseNameObjectsDirectory( pSid, TokenSessionId ) ) //{ // std::cout << "AddAceToBaseNameObjectsDirectory error: " << GetLastError() << std::endl; // return -1; //} if ( !ImpersonateLoggedOnUser( token ) ) { std::cout << "ImpersonateLoggedOnUser error: " << GetLastError() << std::endl; return -1; } STARTUPINFO startupInfo; memset( &startupInfo, 0, sizeof( startupInfo ) ); startupInfo.dwFlags = STARTF_USESHOWWINDOW; startupInfo.wShowWindow = SW_SHOWNORMAL; startupInfo.lpDesktop = L"winsta0\\default"; startupInfo.cb = sizeof( startupInfo ); PROCESS_INFORMATION procInfo; memset( &procInfo, 0, sizeof( procInfo ) ); if ( !SetCurrentDirectory( L"C:\\Windows" ) ) { std::cout << "SetCurrentDirectory error: " << GetLastError() << std::endl; return -1; } if ( !CreateProcessAsUserW( token, L"Notepad.exe", L"Notepad.exe", NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &startupInfo, &procInfo ) ) { std::cout << "CreateProcessAsUser error: " << GetLastError() << std::endl; return -1; } if ( !WaitForSingleObject( token, INFINITE ) ) { std::cout << "WaitForSingleObject error: " << GetLastError() << std::endl; return -1; } }