Metick / DMALibrary

Simple but extensive library for DMA users, made for gamehacking
MIT License
332 stars 71 forks source link

Getting keyboard key states #32

Closed real-pikey closed 3 days ago

real-pikey commented 2 months ago

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.

Metick commented 2 months ago

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

real-pikey commented 2 months ago

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 commented 2 months ago

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.

Metick commented 2 months ago

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

real-pikey commented 2 months ago

Okay, thank you.

real-pikey commented 2 months ago

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 commented 2 months ago

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

Metick commented 2 months ago

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

image

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

real-pikey commented 2 months ago

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

Metick commented 2 months ago

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

real-pikey commented 2 months ago
#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;
}
kWAYTV commented 4 weeks ago

Same issue here, same offsets 22H2 22621

KeinBierVorVier commented 1 week ago

any update?

Metick commented 3 days ago

41 should've solved the issue.