Skip to content

Instantly share code, notes, and snippets.

@jjYBdx4IL
Forked from bitshifter/PurgeStandbyList.cpp
Created December 2, 2020 17:53

Revisions

  1. @bitshifter bitshifter revised this gist Jun 3, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions PurgeStandbyList.cpp
    Original file line number Diff line number Diff line change
    @@ -90,11 +90,11 @@ int _tmain(int argc, _TCHAR* argv[])
    );
    if (status == STATUS_PRIVILEGE_NOT_HELD)
    {
    puts("Insufficient privileges to execute the memory list command");
    fprintf(stderr, "Insufficient privileges to execute the memory list command");
    }
    else if (!NT_SUCCESS(status))
    {
    printf("Unable to execute the memory list command %p", status);
    fprintf(stderr, "Unable to execute the memory list command %p", status);
    }
    return NT_SUCCESS(status);
    }
  2. @bitshifter bitshifter revised this gist Jun 3, 2014. 1 changed file with 0 additions and 21 deletions.
    21 changes: 0 additions & 21 deletions PurgeStandbyList.cpp
    Original file line number Diff line number Diff line change
    @@ -21,27 +21,6 @@ typedef enum _SYSTEM_MEMORY_LIST_COMMAND
    MemoryCommandMax
    } SYSTEM_MEMORY_LIST_COMMAND;

    /*
    NTSYSCALLAPI
    NTSTATUS
    NTAPI
    NtQuerySystemInformation(
    _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
    _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
    _In_ ULONG SystemInformationLength,
    _Out_opt_ PULONG ReturnLength
    );
    NTSYSCALLAPI
    NTSTATUS
    NTAPI
    NtSetSystemInformation(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength
    );
    */

    BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
    {
    BOOL bResult;
  3. @bitshifter bitshifter created this gist Jun 3, 2014.
    121 changes: 121 additions & 0 deletions PurgeStandbyList.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,121 @@
    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>

    #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
    #define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L)

    typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemMemoryListInformation = 80, // 80, q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege)
    } SYSTEM_INFORMATION_CLASS;

    // private
    typedef enum _SYSTEM_MEMORY_LIST_COMMAND
    {
    MemoryCaptureAccessedBits,
    MemoryCaptureAndResetAccessedBits,
    MemoryEmptyWorkingSets,
    MemoryFlushModifiedList,
    MemoryPurgeStandbyList,
    MemoryPurgeLowPriorityStandbyList,
    MemoryCommandMax
    } SYSTEM_MEMORY_LIST_COMMAND;

    /*
    NTSYSCALLAPI
    NTSTATUS
    NTAPI
    NtQuerySystemInformation(
    _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
    _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
    _In_ ULONG SystemInformationLength,
    _Out_opt_ PULONG ReturnLength
    );
    NTSYSCALLAPI
    NTSTATUS
    NTAPI
    NtSetSystemInformation(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength
    );
    */

    BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
    {
    BOOL bResult;
    DWORD dwBufferLength;
    LUID luid;
    TOKEN_PRIVILEGES tpPreviousState;
    TOKEN_PRIVILEGES tpNewState;

    dwBufferLength = 16;
    bResult = LookupPrivilegeValueA(0, lpName, &luid);
    if (bResult)
    {
    tpNewState.PrivilegeCount = 1;
    tpNewState.Privileges[0].Luid = luid;
    tpNewState.Privileges[0].Attributes = 0;
    bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState, (LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState, &tpPreviousState, &dwBufferLength);
    if (bResult)
    {
    tpPreviousState.PrivilegeCount = 1;
    tpPreviousState.Privileges[0].Luid = luid;
    tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
    bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState, dwBufferLength, 0, 0);
    }
    }
    return bResult;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    HANDLE hProcess = GetCurrentProcess();
    HANDLE hToken;
    if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
    {
    fprintf(stderr, "Can't open current process token\n");
    return 1;
    }

    if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
    {
    fprintf(stderr, "Can't get SeProfileSingleProcessPrivilege\n");
    return 1;
    }

    CloseHandle(hToken);

    HMODULE ntdll = LoadLibrary(L"ntdll.dll");
    if (!ntdll)
    {
    fprintf(stderr, "Can't load ntdll.dll, wrong Windows version?\n");
    return 1;
    }

    typedef DWORD NTSTATUS; // ?
    NTSTATUS (WINAPI *NtSetSystemInformation)(INT, PVOID, ULONG) = (NTSTATUS (WINAPI *)(INT, PVOID, ULONG))GetProcAddress(ntdll, "NtSetSystemInformation");
    NTSTATUS (WINAPI *NtQuerySystemInformation)(INT, PVOID, ULONG, PULONG) = (NTSTATUS (WINAPI *)(INT, PVOID, ULONG, PULONG))GetProcAddress(ntdll, "NtQuerySystemInformation");
    if (!NtSetSystemInformation || !NtQuerySystemInformation)
    {
    fprintf(stderr, "Can't get function addresses, wrong Windows version?\n");
    return 1;
    }

    SYSTEM_MEMORY_LIST_COMMAND command = MemoryPurgeStandbyList;
    NTSTATUS status = NtSetSystemInformation(
    SystemMemoryListInformation,
    &command,
    sizeof(SYSTEM_MEMORY_LIST_COMMAND)
    );
    if (status == STATUS_PRIVILEGE_NOT_HELD)
    {
    puts("Insufficient privileges to execute the memory list command");
    }
    else if (!NT_SUCCESS(status))
    {
    printf("Unable to execute the memory list command %p", status);
    }
    return NT_SUCCESS(status);
    }