DMALibrary icon indicating copy to clipboard operation
DMALibrary copied to clipboard

Getting keyboard key states

Open real-pikey opened this issue 1 year ago • 12 comments

This is my first time using this library (it's been a huge help) but I have ran into my first problem. I am not sure if this is a me problem or maybe windows has fixed something, but I am trying to get the key state on my main pc using the mem.GetKeyboard()->InitKeyboard() and mem.GetKeyboard()->IsKeyDown(VK_ESCAPE). I have tried using the kmbox monitor but that did not work as well so I thought I would try this way but it just doesn't seem to throw any errors. I did start logging values and gafAsyncKeyStateExport seemed the most important so this is what mine prints as: gafAsyncKeyStateExport: ffffa78f76d4c690, it doesn't seem to be invalid, so I am not too sure on what is incorrect. Any help would be appreciated. Thanks.

real-pikey avatar Sep 02 '24 12:09 real-pikey

it's probably in paged out memory, so you gotto restart your computer or restart winlogon.exe

Metick avatar Sep 02 '24 21:09 Metick

I completely shutdown my computer waited 5 seconds, then started it back up but it still seems I cannot read the key state. I have it setup like this at the moment #define KEY_A 0x04 if (!mem.GetKeyboard()->InitKeyboard()) { std::cout << "Failed to initialize keyboard hotkeys through kernel." << std::endl; this_thread::sleep_for(chrono::seconds(5)); return 1; }

while (true) { if (mem.GetKeyboard()->IsKeyDown(KEY_A)) cout << "yes"; else cout << "no"; Sleep(1000); }

which I assume is fine, and I just hold my a key down but it just keeps printing no.

real-pikey avatar Sep 03 '24 02:09 real-pikey

I realised that I was using a bit of an older version (without the Ubr), and I just tried to update it but it constantly crashes. long story short it can't seem to get the value from my registry so I manually put the value into InputManager.cpp and then attempted it again but it still cannot get my key state.

real-pikey avatar Sep 03 '24 03:09 real-pikey

I realised that I was using a bit of an older version (without the Ubr), and I just tried to update it but it constantly crashes. long story short it can't seem to get the value from my registry so I manually put the value into InputManager.cpp and then attempted it again but it still cannot get my key state.

Reverse win32kbase & win32ksgd.sys and see if the offsets are still correct on the windows versions you're running. refer to #31 on how to find the offsets

Metick avatar Sep 03 '24 11:09 Metick

Okay, thank you.

real-pikey avatar Sep 03 '24 11:09 real-pikey

I opened win32kbase.sys with ida and found this. is this correct? image

and also for the win32ksgd.sys am I looking for the same function name or what exactly am I looking for in that driver?

real-pikey avatar Sep 03 '24 11:09 real-pikey

Just checked the code and they are both the same (0x36A8)

real-pikey avatar Sep 03 '24 11:09 real-pikey

That seems correct, try also opening win32ksgd.sys and find gSessionGlobalSlots

image

and confirm if it's still 0x3110 to the ptr

Metick avatar Sep 03 '24 11:09 Metick

It seems to all be correct, if you want, for more information, I can post my current inputmanager.cpp in case I accidently changed something in there. image

real-pikey avatar Sep 03 '24 11:09 real-pikey

I guess you can send that over incase you did do smth wrong by accident

Metick avatar Sep 03 '24 11:09 Metick

#include "pch.h"
#include "InputManager.h"
#include "Registry.h"
#include "Memory/Memory.h"

bool c_keys::InitKeyboard()
{
	std::string win = registry.QueryValue("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\CurrentBuild", e_registry_type::sz);
	int Winver = 0;
	if (!win.empty())
		Winver = std::stoi(win);
	else
		return false;

	std::string ubr = registry.QueryValue("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\UBR", e_registry_type::dword);
	int Ubr = 4037;


	this->win_logon_pid = mem.GetPidFromName("winlogon.exe");
	if (Winver > 22000)
	{
		auto pids = mem.GetPidListFromName("csrss.exe");
		for (size_t i = 0; i < pids.size(); i++)
		{
			auto pid = pids[i];
			uintptr_t tmp = VMMDLL_ProcessGetModuleBaseU(mem.vHandle, pid, const_cast<LPSTR>("win32ksgd.sys"));
			uintptr_t g_session_global_slots = tmp + 0x3110;
			uintptr_t user_session_state = 0;
			for (int i = 0; i < 4; i++)
			{
				user_session_state = mem.Read<uintptr_t>(mem.Read<uintptr_t>(mem.Read<uintptr_t>(g_session_global_slots, pid) + 8 * i, pid), pid);
				if (user_session_state > 0x7FFFFFFFFFFF)
					break;
			}
			if (Winver >= 22631 && Ubr >= 3810)
				gafAsyncKeyStateExport = user_session_state + 0x36A8;
			else
				gafAsyncKeyStateExport = user_session_state + 0x3690;
			if (gafAsyncKeyStateExport > 0x7FFFFFFFFFFF)
				break;
		}
		if (gafAsyncKeyStateExport > 0x7FFFFFFFFFFF)
			return true;
		return false;
	}
	else
	{
		std::cout << "in else";
		PVMMDLL_MAP_EAT eat_map = NULL;
		PVMMDLL_MAP_EATENTRY eat_map_entry;
		bool result = VMMDLL_Map_GetEATU(mem.vHandle, mem.GetPidFromName("winlogon.exe") | VMMDLL_PID_PROCESS_WITH_KERNELMEMORY, (LPSTR)"win32kbase.sys", &eat_map);
		if (!result)
			return false;

		if (eat_map->dwVersion != VMMDLL_MAP_EAT_VERSION)
		{
			VMMDLL_MemFree(eat_map);
			eat_map_entry = NULL;
			return false;
		}

		for (int i = 0; i < eat_map->cMap; i++)
		{
			eat_map_entry = eat_map->pMap + i;
			if (strcmp(eat_map_entry->uszFunction, "gafAsyncKeyState") == 0)
			{
				gafAsyncKeyStateExport = eat_map_entry->vaFunction;

				break;
			}
		}

		VMMDLL_MemFree(eat_map);
		eat_map = NULL;
		if (gafAsyncKeyStateExport > 0x7FFFFFFFFFFF)
			return true;
		return false;
	}
}

void c_keys::UpdateKeys()
{
	uint8_t previous_key_state_bitmap[64] = { 0 };
	memcpy(previous_key_state_bitmap, state_bitmap, 64);

	VMMDLL_MemReadEx(mem.vHandle, this->win_logon_pid | VMMDLL_PID_PROCESS_WITH_KERNELMEMORY, gafAsyncKeyStateExport, (PBYTE)&state_bitmap, 64, NULL, VMMDLL_FLAG_NOCACHE);
	for (int vk = 0; vk < 256; ++vk)
		if ((state_bitmap[(vk * 2 / 8)] & 1 << vk % 4 * 2) && !(previous_key_state_bitmap[(vk * 2 / 8)] & 1 << vk % 4 * 2))
			previous_state_bitmap[vk / 8] |= 1 << vk % 8;
}

bool c_keys::IsKeyDown(uint32_t virtual_key_code)
{
	if (gafAsyncKeyStateExport < 0x7FFFFFFFFFFF)
		return false;
	if (std::chrono::system_clock::now() - start > std::chrono::milliseconds(5))
	{
		UpdateKeys();
		start = std::chrono::system_clock::now();
	}
	return state_bitmap[(virtual_key_code * 2 / 8)] & 1 << virtual_key_code % 4 * 2;
}

real-pikey avatar Sep 03 '24 12:09 real-pikey

Same issue here, same offsets 22H2 22621

kWAYTV avatar Oct 11 '24 11:10 kWAYTV

any update?

CatCaller avatar Oct 29 '24 16:10 CatCaller

#41 should've solved the issue.

Metick avatar Nov 06 '24 10:11 Metick