Gettin HANDLE AND PASS IT TO USERMODE -- INVALID_KERNEL_HANDLE[2021]

I want to Hijack handles. I go through the handle table and search for all handles who are process handles.

NTSTATUS status = ZwQuerySystemInformation(SystemHandleInformation, NULL, 0, &bytes);
PSYSTEM_HANDLE_TABLE_INFORMATION SysHandleTable = reinterpret_cast<PSYSTEM_HANDLE_TABLE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool, bytes, 0x74616731));
ZwQuerySystemInformation(SystemHandleInformation, SysHandleTable, bytes, NULL);
bytes = bytes + (SysHandleTable->HandleCount * sizeof(_SYSTEM_HANDLE_TABLE_ENTRY)) + 256; //256 for good measures
ExFreePoolWithTag(SysHandleTable, 0x74616731);

SysHandleTable = reinterpret_cast<PSYSTEM_HANDLE_TABLE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool, bytes, 0x74616731));
status = ZwQuerySystemInformation(SystemHandleInformation, SysHandleTable, bytes, NULL);
if (NT_SUCCESS(status))
{
	for (ULONG i = 0; i < SysHandleTable->HandleCount; i++)
	{
		if (SysHandleTable->Handles[i].Handle != NULL)
		{
			if (SysHandleTable->Handles[i].ObjectTypeNumber == 0x7) // Is the current Handle a process handle
			{

After I’ve found a process handle my code is getting the PEPROCESS of the process the handle belongs to
PEPROCESS processToHijack;
HANDLE procHandle = NULL;

				status = PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(SysHandleTable->Handles[i].ProcessId), &processToHijack);
				if (NT_SUCCESS(status))
				{

Up to this point I haven’t had any problems but if I try to ObOpenObjectByPointer my VM crashes and gives me a BSOD with the error code being: INVALID_KERNEL_HANDLE.
status = ObOpenObjectByPointer(processToHijack, NULL, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &procHandle);

Why am I doing this? - I want to hijack a existing handle to a process. I want that handle to be a process handle. I am through all process handles and “opening a handle to the process that the handle belogns to” so that i can ZwDuplicateObject the original process handle and compare its UniqueProcessId with the process i want to hijack. If the handle isn’t a handle to my process i close all opened handles and continue with the next one. If i find a handle i am giving it to my process which controlls the driver and closing the original one, effectively hijacking the handle.

Full code:
void KernelMemory::GetHandleToProcess(HANDLE _ProcessID, void* _Response)
{
ULONG bytes;
HANDLE hijackHandle = NULL;
HANDLE procHandle = NULL;
PEPROCESS processToHijack;

NTSTATUS status = ZwQuerySystemInformation(SystemHandleInformation, NULL, 0, &bytes);
PSYSTEM_HANDLE_TABLE_INFORMATION SysHandleTable = reinterpret_cast<PSYSTEM_HANDLE_TABLE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool, bytes, 0x74616731));
ZwQuerySystemInformation(SystemHandleInformation, SysHandleTable, bytes, NULL);
bytes = bytes + (SysHandleTable->HandleCount * sizeof(_SYSTEM_HANDLE_TABLE_ENTRY)) + 256; //256 for good measures
ExFreePoolWithTag(SysHandleTable, 0x74616731);

SysHandleTable = reinterpret_cast<PSYSTEM_HANDLE_TABLE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool, bytes, 0x74616731));
status = ZwQuerySystemInformation(SystemHandleInformation, SysHandleTable, bytes, NULL);
if (NT_SUCCESS(status))
{
	for (ULONG i = 0; i < SysHandleTable->HandleCount; i++)
	{
		if (SysHandleTable->Handles[i].Handle != NULL)
		{
			if (SysHandleTable->Handles[i].ObjectTypeNumber == 0x7)
			{
				if (procHandle != NULL || hijackHandle != NULL)
				{
					ZwClose(procHandle); ZwClose(hijackHandle);
				}

				PEPROCESS processToHijack;
				HANDLE procHandle = NULL;

				status = PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(SysHandleTable->Handles[i].ProcessId), &processToHijack);
				if (NT_SUCCESS(status))
				{
					status = ObOpenObjectByPointer(processToHijack, NULL, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &procHandle);
					
					if (NT_SUCCESS(status))
					{

					}
					DbgPrintEx(0, 0, "Error: %x", status);
				}
				ZwClose(procHandle);
				ZwClose(hijackHandle);
				ObDereferenceObject(processToHijack);
				/* Return the PID */

					/*if (reinterpret_cast<HANDLE>(ProcessBasic.UniqueProcessId) == _ProcessID)
					{
						DbgPrintEx(0, 0, "%i is a Process Handle and a Handle to our target Proccess", i);

						DbgPrintEx(0, 0, "%i Passed all checks", i);

						status = ObDuplicateObject(process, reinterpret_cast<HANDLE>(SysHandleTable->Handles[i].Handle), PsGetCurrentProcess(), &reinterpret_cast<HANDLE>(_Response), NULL, NULL, DUPLICATE_CLOSE_SOURCE, ExGetPreviousMode()); //Might have to parse my PID
						if (NT_SUCCESS(status)) { ExFreePoolWithTag(SysHandleTable, 0x74616731); break; }
					}*/
			}
		}
		continue;
	}
	DbgPrintEx(0, 0, "No more checking");
}
DbgPrintEx(0, 0, "FreeingPool");
ExFreePoolWithTag(SysHandleTable, 0x74616731);
return;

}

How is this code being called? Remember, unless you are running in the system process, you must pass OBJ_KERNEL_HANDLE.

My unsigned driver gets mapped into ring0 but i never directly call any functions from my driver, I call it by hooking into a officials driver function and hijacking the parameters if someone calls that function and if I can cast it to my defined struct I execute the given operation otherwise i return to the parameters to the original function and let it do its thing. In the userspace I call the corresponding function with a void* to my struct (my driver and my userspace ctrl have the same structure if it wasn’t clear by now so that a flawless conversion is possible)

malware?

whut?

‘malware’ as in what are you trying to do?

Mark Roddy

As in “we all are not sure we want to answer your question, because it sounds to at least some of us like you might be writing malware, and we’re not interested in helping in that case”

Clear enough?

Peter

Ah I understand. I am sorry for not clarifying but this has nothing to do with malware and I want to clarify that I am not interested in that topic either. I come from the gamehacking community and this driver I am currently working on is rather only for research purposes. I also want to note that just because I am a game hacker this doesn’t make me a cheater. I enjoy reversing game files and taking a game apart but I am not interested in ruining the online community of a game.

First, you really should know that your research project is (most likely) in violation of DMCA [https://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act] so if you put it anywhere other than on your hard drive your provider will get a takedown notice, second you mention that this will be started from an unsigned driver which means you’re either in test mode or you’ve turned off SecureBoot (which few if any modern games will run under) and finally essentially you’re describing a call gate handler [ https://medium.com/@fsx30/hooking-heavens-gate-a-wow64-hooking-technique-5235e1aeed73 ] which was long ago handled by the OS so you’re probably not going to get what you think you’re going to get …

Hard pass from this corner …

We get the strangest questions from the “I’m building a game cheat” and “I’m building software to prevent game cheating” folks…

I’m “out” on any of it, personally… Right down to turning away potential clients ask us to develop “anti-cheat” software.

Peter

First of all I want to apologize if for reviving a old post and (from your perspektive) breaking the 6th rule. (6. Asking about how to implement malware, or requesting help with techniques that are commonly used for the implementation of malware. ).

Secondly I would like to know as to why I would violate DMCA. Either way I want to state that I am neither in secure boot nor did i turn test mode on. There are various ways of loading a unsigned driver in normal Windows. Most of them use the vulnerable Capcom driver to do so but I have the feeling that this is kinda offtopic.

I want to further clarify what I am trying to do mainly because I hope it contributes to a solution but also to hopefully clear all of your doubts. What I am trying to do is called handle hijacking. I want to duplicate a target handle into my user mode application. This common practice when it comes to reversing games. The games blocks cheat engine and various other programs from opening a process handle to the game. To bypass this a handle hijack is needed. There are quite some sources out there that do exactly what I am currently describing. (Just google it. There are good sources on guidedhacking and unknowncheats). The difference between what they are doing and what I want to do is, that they are purely operating in usermode. Let’s take a small break from the tech stuff. First of all thank you for reading this far. I wrote this whole block to “proof” that what I am doing is by no means something that is uncommon. I could just C+P the existing methodes change some lines and go on with my day but that would clearly defeat my purpose. I am doing all this to get a deeper understanding of windows and how it manages things in the ring0 realm. I can understand if you still have your doubts but I came here seeking help or at least some guidance.

Nearly all of the residents of this list are professional programmers. For us, “various ways of loading a unsigned driver in normal Windows” is malware, as is the handle hijacking you describe. I don’t care whether it is common or not. It is not productive, and it is of questionable legality.

1 Like

I can understand why loading a unsigned drivers is considered malware. However, I don’t fully agree with your second statement. Strictly labeling something as malware without considering other use cases is, in my opinion, very ignorant. It is as if you say a cheat is malware. If you are making use of techniques that are considered malware, it doesn’t mean that it actually is malware. And for everyone that says otherwise, there are tons of anti-virus programs that offer extra websites to report false positives. Sadly I have the feeling that most of the people here are going to have the same opinion as you have.

What Mr. Roberts said.

I like this discussion less and less. So…I’m going with my gut and locking this thread.

I don’t want to have any of these discussions: loading unsigned drivers, handle hijacking, etc.

Sorry OP. You seem like a reasonable sort, but…. We clearly live in different worlds.

Thread locked.

2 Likes