
Driver kernel-mode di Windows con client user-mode che espone lettura/scrittura di memoria fisica e virtuale basata su IOCTL, page table walking, pattern scanning ed emulazione di input per il cheating nei giochi.
██╗ ██╗████████╗██╗ ██╗██╗██╗ ██╗███╗ ███╗
██║ ██║╚══██╔══╝██║ ██║██║██║ ██║████╗ ████║
██║ ██║ ██║ ███████║██║██║ ██║██╔████╔██║
██║ ██║ ██║ ██╔══██║██║██║ ██║██║╚██╔╝██║
███████╗██║ ██║ ██║ ██║██║╚██████╔╝██║ ╚═╝ ██║
╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═╝
Framework di driver in modalità kernel per Windows con client in modalità utente
[!IMPORTANT]
Ottieni il progetto completo
I file della soluzione sono disponibili tramite il server Discord.
Interessato all'acquisto del codice sorgente completo? Contattami su Telegram o Discord: @tonythimself.
Lithium è un driver in modalità kernel per Windows (lithium-kernel) abbinato a un client in modalità utente (lithium-usermode). Comunica tramite un'interfaccia IOCTL personalizzata ed espone primitive di manipolazione della memoria a basso livello, page table walking e controllo dei dispositivi di input.
| Funzionalità | Descrizione |
|---|---|
| Lettura/Scrittura memoria fisica | Lettura/scrittura diretta di indirizzi fisici tramite MmCopyMemory |
| Lettura/Scrittura memoria virtuale | Accesso alla memoria virtuale cross-processo tramite MmCopyVirtualMemory |
| Risoluzione DTB | Estrazione della directory table base tramite enumerazione del database PFN |
| Page Table Walking | Traduzione degli indirizzi lineari con caching dei livelli PML4/PDPT/PD/PT |
| Pattern Scanning | Scansione di firme in stile IDA nella memoria del processo |
| Allocazione di memoria | ZwAllocateVirtualMemory nel contesto del processo target |
| Protezione di memoria | ZwProtectVirtualMemory nel contesto del processo target |
| Emulazione del mouse | Input del mouse a livello kernel tramite hook della callback del servizio MouClass |
| Thread Hiding | Spoofing dei campi ETHREAD (indirizzo di avvio, CID, orario di creazione, ecc.) |
| Disattivazione callback NMI | Soppressione delle callback NMI per l'evasione del debugger |
| Pulizia del pool | Rimozione delle voci della big pool table dal tracker del pool del kernel |
lithium/
├── lithium-kernel/ # Kernel-mode driver (KMDF)
│ ├── entry.cpp # DriverEntry entry point
│ ├── core/
│ │ ├── dispatch/ # IOCTL dispatch and request routing
│ │ ├── requests/
│ │ │ ├── directory-table-base/ # DTB resolution & page table walk
│ │ │ ├── image-base/ # Process module base retrieval
│ │ │ ├── mouse/ # Mouse input emulation via MouClass
│ │ │ ├── read-write/ # Physical and virtual memory R/W
│ │ │ └── virtual-memory/ # Allocate, protect, query, pattern scan
│ │ └── utilities/
│ │ ├── kernel/ # Module enumeration, NMI, thread ops
│ │ └── ... # Pool cleaner, CRT shim
│ └── dependencies/
│ ├── additional/
│ │ ├── crt/ # Minimal CRT implementation
│ │ ├── security/ # skCrypter string encryption, oxorany
│ │ └── structures/ # Shared invoke data structures
│ └── includes.hpp # Master include header
│
└── lithium-usermode/ # User-mode client
├── entry.cpp # Client entry point
├── core/
│ └── driver/ # IOCTL communication layer
└── dependencies/
├── additional/
│ └── structs.hpp # Page table entry unions & helpers
└── includes.hpp
La comunicazione viene stabilita tramite l'hook della routine di dispatch IOCTL di un driver esistente (ProcObsrvesx.sys). Al momento del caricamento, il modulo kernel individua il driver target, cerca il suo gestore di dispatch IRP e lo sovrascrive con un trampolino verso l'hooked_ioctl di lithium. Il client in modalità utente apre \\.\ProcObsrvesx e tutti gli IOCTL vengono reindirizzati in modo trasparente attraverso l'hook.
| Codice | Struttura di input | Azione |
|---|---|---|
invoke_base | base_invoke { pid, handle } | Recupera l'image base del processo |
invoke_dtb | dtb_invoke { pid, dtb } | Risolve la directory table base |
invoke_read | read_invoke { pid, directory_table, address, buffer, size } | Legge la memoria fisica |
invoke_write | write_invoke { pid, directory_table, address, buffer, size } | Scrive la memoria fisica |
invoke_read_virtual | read_virtual_invoke { pid, address, buffer, size } | Legge la memoria virtuale |
invoke_write_virtual | write_virtual_invoke { pid, address, buffer, size } | Scrive la memoria virtuale |
invoke_allocate | allocate_invoke { pid, type, protection, address, size } | Alloca memoria virtuale |
invoke_protect | protect_invoke { pid, protection, address, size } | Modifica la protezione della memoria |
invoke_virtual_query | query_virtual_invoke { pid, address, mbi } | Interroga le informazioni sulla memoria virtuale |
invoke_pattern_scan | pattern_invoke { pid, signature, address, pattern_address } | Scansione pattern in memoria |
invoke_move_mouse | mouse_invoke { x, y, flags, button_flags } | Emula l'input del mouse |
Il driver itera sugli intervalli di memoria fisica restituiti da MmGetPhysicalMemoryRanges, percorre il database PFN per individuare la voce PML4 auto-referenziante e convalida ogni livello della page table per confermare la corretta directory table base per un dato processo.
La traduzione da lineare a fisico attraversa la gerarchia a quattro livelli della page table x64 (PML4 → PDPT → PD → PT) con caching per livello. Il supporto per le large page (2MB / 1GB) è incluso su base best-effort.
Il driver individua gli oggetti driver MouClass e MouHID, risolve la MouseClassServiceCallback dall'estensione del dispositivo HID e inietta pacchetti MOUSE_INPUT_DATA direttamente nella catena di callback.
I campi chiave di ETHREAD — orario di creazione, indirizzo di avvio, indirizzo di avvio Win32, kernel stack, CID e stato di uscita — vengono salvati e sostituiti con valori benigni o nulli. Alla disattivazione, i valori originali vengono ripristinati prima della terminazione del thread.
lithium.sln in Visual Studiolithium-kernel → lithium-kernel.syslithium-usermode → lithium-usermode.exeOppure tramite MSBuild:
msbuild lithium.sln /p:Configuration=Release /p:Platform=x64
#include <core/driver/driver.hpp>
g_driver->initialize_handle();
DWORD pid = g_driver->get_process_id(L"target.exe");
g_driver->attach(pid);
g_driver->image_base = g_driver->get_image_base(0);
g_driver->dtb = g_driver->resolve_directory_table_base();
auto value = g_driver->read<uintptr_t>(g_driver->image_base + 0xOFFSET);
g_driver->mouse_event(-10, -10, 0, 0);