2017-02-20 6 views
1

ich so große Seiten in meiner Anwendung verwenden mag:Aktivieren große Seiten in WIndows programmatisch

VirtualAlloc(NULL, n_bytes, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE, PAGE_READWRITE); 

ich große Seiten für die aktuellen Benutzer während der Installation aktiviert werden soll, während Admin-Rechte mit erhöhten . Hat jemand Code, um große Seiten programmgesteuert zu aktivieren?

+0

Sie vergessen 'MEM_COMMIT' Flag. Aufruf 'VirtualAlloc (NULL, n_bytes, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); in welchem ​​Problem? – RbMm

+0

@RbMm Korrigiert. Wie auch immer, bevor ich es anrufe, muss ich 'SeLockMemoryPrivilege' privelege für den Benutzeraccount erhalten https://msdn.microsoft.com/en-us/library/windows/desktop/aa366720(v=vs.85).aspx –

+0

ja, brauchen. sind Probleme bekommen 'SeLockMemoryPrivilege'? – RbMm

Antwort

1

Ich poste, was ich gesammelt habe.

Die allgemeine Idee:

  1. Aktivieren große Seiten für das aktuelle Benutzerkonto. (Erfordert Admin-Rechte).
  2. Aktivieren Sie große Seiten für das aktuelle Prozesstoken. (Erfordert Admin-Rechte).
  3. Ordnen Sie den Speicher (granulare bis große Seitengröße, 2 MB, in der Tat).

Wenn Sie UAC haben properly disabled, müssen Sie Schritt 1 nur einmal mit Admin-Rechten auszuführen. Wenn Sie die Benutzerkontensteuerung aktiviert haben, müssen Sie sie immer mit Administratorrechten ausführen.

#define UNICODE 
#define _UNICODE 

#include <windows.h> 
#include <ntsecapi.h> 
#include <ntstatus.h> 
#include <Sddl.h> 

void InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String) 
{ 
    DWORD StringLength; 

    if (String == NULL) { 
     LsaString->Buffer = NULL; 
     LsaString->Length = 0; 
     LsaString->MaximumLength = 0; 
     return; 
    } 

    StringLength = wcslen(String); 
    LsaString->Buffer = String; 
    LsaString->Length = (USHORT)StringLength * sizeof(WCHAR); 
    LsaString->MaximumLength = (USHORT)(StringLength + 1) * sizeof(WCHAR); 
} 

NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle) 
{ 
    LSA_OBJECT_ATTRIBUTES ObjectAttributes; 
    LSA_UNICODE_STRING ServerString; 
    PLSA_UNICODE_STRING Server = NULL; 

    // 
    // Always initialize the object attributes to all zeroes. 
    // 
    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); 

    if (ServerName != NULL) { 
     // 
     // Make a LSA_UNICODE_STRING out of the LPWSTR passed in 
     // 
     InitLsaString(&ServerString, ServerName); 
     Server = &ServerString; 
    } 

    // 
    // Attempt to open the policy. 
    // 
    return LsaOpenPolicy(
     Server, 
     &ObjectAttributes, 
     DesiredAccess, 
     PolicyHandle 
    ); 
} 

NTSTATUS SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName, BOOL bEnable) 
{ 
    LSA_UNICODE_STRING PrivilegeString; 

    // 
    // Create a LSA_UNICODE_STRING for the privilege name. 
    // 
    InitLsaString(&PrivilegeString, PrivilegeName); 

    // 
    // grant or revoke the privilege, accordingly 
    // 
    if (bEnable) { 
     return LsaAddAccountRights(
      PolicyHandle,  // open policy handle 
      AccountSid,   // target SID 
      &PrivilegeString, // privileges 
      1     // privilege count 
     ); 
    } 
    else { 
     return LsaRemoveAccountRights(
      PolicyHandle,  // open policy handle 
      AccountSid,   // target SID 
      FALSE,    // do not disable all rights 
      &PrivilegeString, // privileges 
      1     // privilege count 
     ); 
    } 
} 

void main() 
{ 
    HANDLE hToken = NULL; 

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 
    { 
     applog(LOG_INFO, "OpenProcessToken failed. GetLastError returned: %d\n", GetLastError()); 
     return -1; 
    } 

    DWORD dwBufferSize = 0; 

    // Probe the buffer size reqired for PTOKEN_USER structure 
    if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwBufferSize) && 
     (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) 
    { 
     applog(LOG_INFO, "GetTokenInformation failed. GetLastError returned: %d\n", GetLastError()); 

     // Cleanup 
     CloseHandle(hToken); 
     hToken = NULL; 

     return -1; 
    } 

    PTOKEN_USER pTokenUser = (PTOKEN_USER) malloc(dwBufferSize); 

    // Retrieve the token information in a TOKEN_USER structure 
    if (!GetTokenInformation(
     hToken, 
     TokenUser, 
     pTokenUser, 
     dwBufferSize, 
     &dwBufferSize)) 
    { 
     applog(LOG_INFO, "GetTokenInformation failed. GetLastError returned: %d\n", GetLastError()); 

     // Cleanup 
     CloseHandle(hToken); 
     hToken = NULL; 

     return -1; 
    } 

    // Print SID string 
    LPWSTR strsid; 
    ConvertSidToStringSid(pTokenUser->User.Sid, &strsid); 
    applog(LOG_INFO, "User SID: %S\n", strsid); 

    // Cleanup 
    CloseHandle(hToken); 
    hToken = NULL; 

    NTSTATUS status; 
    LSA_HANDLE policyHandle; 

    if (status = OpenPolicy(NULL, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &policyHandle)) 
    { 
     applog(LOG_INFO, "OpenPolicy %d", status); 
    } 

    // Add new privelege to the account 
    if (status = SetPrivilegeOnAccount(policyHandle, pTokenUser->User.Sid, SE_LOCK_MEMORY_NAME, TRUE)) 
    { 
     applog(LOG_INFO, "OpenPSetPrivilegeOnAccountolicy %d", status); 
    } 

    // Enable this priveledge for the current process 
    hToken = NULL; 
    TOKEN_PRIVILEGES tp; 

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) 
    { 
     applog(LOG_INFO, "OpenProcessToken #2 failed. GetLastError returned: %d\n", GetLastError()); 
     return -1; 
    } 

    tp.PrivilegeCount = 1; 
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &tp.Privileges[0].Luid)) 
    { 
     applog(LOG_INFO, "LookupPrivilegeValue failed. GetLastError returned: %d\n", GetLastError()); 
     return -1; 
    } 

    BOOL result = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
    DWORD error = GetLastError(); 

    if (!result || (error != ERROR_SUCCESS)) 
    { 
     applog(LOG_INFO, "AdjustTokenPrivileges failed. GetLastError returned: %d\n", error); 
     return -1; 
    } 

    // Cleanup 
    CloseHandle(hToken); 
    hToken = NULL; 

    SIZE_T pageSize = GetLargePageMinimum(); 

    // Finally allocate the memory 
    char *largeBuffer = VirtualAlloc(NULL, pageSize * N_PAGES_TO_ALLOC, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); 
    if (largeBuffer) 
    { 
     applog(LOG_INFO, "VirtualAlloc failed, error 0x%x", GetLastError()); 
    } 
} 
Verwandte Themen