Indeed, good resource to learn from. I devote to you and XenoMC code my learning of the Handle Manipulation.
2 ~ 3 days after you published this video, I got bored and I went write a small mc app in the .NET framework using the library I had ported from xenomc to .NET some time ago using the Handle Manipulation technique, but this time I was checking (almost all P/Invoke calls, except the NtQuery... functions) if everything ran smooth by .NET P/Invoke error handling strategy (which is basically GetLastError followed by FormatMessage wrappers).
By this way, I remember that "ReleaseMutex" actually fails to close the mutex, setting the last error to something like "Invalid access to handle outside the current process" (remote access). Passing the DUPLICATE_CLOSE_SOURCE seems to be enough to release the mutex in the DuplicateObject function (personally, I call CloseHandle after DuplicateObject (no matter if true or false) to clean things up). Also, just querying the OBJECT_NAME_INFORMATION seems to be enough to grab the system handle's name without querying the OBJECT_TYPE_INFORMATION
For NtQuerySystemInformation and NtQueryObject, I liked a nice trick I read somewhere that instead of allocating some previous fixed number of bytes (0x1000) as example, I'm using "while STATUS_INFO_LENGTH_MISMATCH ... reevaluate the function allocating the last parameter returned (needed bytes)"
This snippet explains better than my shitty english
Code:
int size = 0;
int returnLength = 0;
IntPtr handlePointer = Marshal.AllocHGlobal(size); // allocating 0 bytes
try
{
uint NTSTATUS = NativeMethods.NtQuerySystemInformation(
NativeMethods.CNST_SYSTEM_HANDLE_INFORMATION,
handlePointer,
size,
out returnLength
);
while (NTSTATUS == NativeMethods.STATUS_INFO_LENGTH_MISMATCH) // in the first call, this condition will occur, because we allocated 0 bytes
{
size = returnLength;
Marshal.FreeHGlobal(handlePointer);
handlePointer = Marshal.AllocHGlobal(returnLength); // now, I'm allocating the correct amount of bytes
NTSTATUS = NativeMethods.NtQuerySystemInformation(
NativeMethods.CNST_SYSTEM_HANDLE_INFORMATION,
handlePointer,
size,
out returnLength
);
}
if (NTSTATUS != NativeMethods.STATUS_SUCCESS)
return;
.
.
.
}