Click here to Skip to main content
12,509,509 members (62,043 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

259.7K views
187 downloads
3 bookmarked
Posted

Empty Standby List in Windows

, 31 Dec 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
How to create an empty standby list in Windows

Introduction

The makers of process hacker know the Windows kernel inside and out!  Fortunately for them, they are also fluent in C++: the language that the Windows kernel was designed on. For the rest of us, we struggle to make C# perform similar functions. One of those functions is the ability to release memory from the windows standby memory. That is what we will do here.

Credits

Obviously, the procedures used here are fundamentally taken from Process Hacker's source code - Thanks!

Next, the hardest part is getting the Kernel privileges. While I've significantly tweaked the code, my thanks must also go to Nick Lowe - Thanks!

Note: I have trimmed almost all code that is not related to the task itself. If you want to know more about either project, please visit their websites.

Step One: Setting Kernel Privileges

Microsoft has designed the API to take a structure that contains an array of structures. There are no good Marshaling procedures for this - they either assume the array is length=1 or require that the size of the array be predetermined at compilation. For this purpose, I designed a class that holds the exact structure that Microsoft requires in unmanaged memory via an System.IntPtr. I had to resort to one unsafe procedure at this point ... but I'm sure that can be bypassed with more work in the future.

[return: MarshalAs(UnmanagedType.Bool)]
[SuppressUnmanagedCodeSecurity, DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(AccessTokenHandle accessTokenHandle,
[MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, IntPtr NewPriviledges,
	Int32 bufferLength, ref IntPtr PriorPriviledges, out Int32 returnLength);	

Combining my class with Nick Lowe's privilege code, we can setup our kernel privileges with:

AccessTokenHandle
	myProcessToken = new AccessTokenHandle(System.Diagnostics.Process.GetCurrentProcess(),
	ProcessPrivileges.TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query);
myProcessToken.EnablePrivilege(Privilege.Debug, Privilege.ProfileSingleProcess);	

Step Two: Sending the Command to the Kernel

This time, Microsoft simply wants an int array. These Marshal easily, so all we need is:

[DllImport("ntdll.dll")]
public static extern NtStatus NtSetSystemInformation
(SYSTEM_INFORMATION_CLASS InfoClass, int[] Info, uint Length);

NativeMethods.NtStatus
	result = 0;
int[]
	arr = new int[] { (int)Commands.MemoryPurgeStandbyList };
result = NativeMethods.NtSetSystemInformation
(NativeMethods.SYSTEM_INFORMATION_CLASS.SystemMemoryListInformation,
arr, (uint)(sizeof(int) * arr.Length));
if (result > 0)
	throw new System.ComponentModel.Win32Exception();	

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Member 10018957
Systems Engineer RedDotNet
United States United States
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160927.1 | Last Updated 1 Jan 2015
Article Copyright 2015 by Member 10018957
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid