Using a very simple hook, you can change the meaning of what the user is typing and put anything else. The process is even easier if what you want is to replace the characters typed one by one.
This is a very simple program that uses this technique to make the Russian keyboard layout easy to learn. I made it for myself, but maybe it can be useful for anyone else. At least the hook technique, flexible enough, is worthy to learn.
Why map characters
An alphabet is one of the many ways to represent the words of a language in writing. A written word is a set of letters meaning the sounds we use to pronounce this word. Every different sound is a different phoneme.
Even though the Russian alphabet is so different from the Latin alphabet, they share many phonemes. This means that we can get some Cyrillic letters and replace them directly to some Latin letters. However, after the translation, the position of this letter normally is different from the Latin keyboard layout. So we have a Latin letter in a different place in the keyboard. If made a near translation between the both, the Latin letters will be disposed like this:
Ii is a bit different from the well-known qwert asdfg, isn't?
When typing using this pseudo-keyboard layout, the Latin layout is replaced for the Russian layout in a Latin letters set. So a person can practice a Russian keyboard even using the Latin alphabet. Cool, isn't? I can code using the misplaced letters, because the final result is the same. I just need to train my fingers to beat the same letters in different places. This way, if I would need to use Cyrillic, I already know where every Russian letter is supposed to be in the Russian keyboard.
Obs: Almost all the Russian letters can be replaced using a Latin one, but there're some exceptions. So I chose to ignore the translation in this case and put another letter instead. It is not necessarily a good choice for the phoneme, but it is required in order to write using all the available Latin letters.
It would be nice to know something about the Win32 API function
SetWindowsHookEx() and how to use it for message hooks.
Using the code
The code itself is already a useful program (at least for me +). You can use it for typing training in another keyboard layout system. The only thing to change inside the code is the correspondence of the letters, located inside the arrays below:
const TCHAR g_tzRussAlphabet =
const TCHAR g_tzPortAlphabet =
The handling code is quite simple. It is about an original charset array search and consequent replace for its Latin brother (the same index inside another array):
switch( pMsg->message )
LPTSTR ptzChar =
_tcschr(g_tzRussAlphabet, (TCHAR) pMsg->wParam);
if( ptzChar )
size_t offset = ptzChar - g_tzRussAlphabet;
pMsg->wParam = (WPARAM) g_tzPortAlphabet[offset];
Points of Interest
While debugging a project that makes message hooks globally, the attention must be multiplied for three times or more. Any mistake you do inside the callback function can put the system down (like a
MessageBox() called for any message, for example). However, once you're debugging a specific message for a specific process, generally the only process that will freeze will be the debuggee itself and the ones that depends directly on some frozen action.
15 Feb 2007 - updated the code to work with VS6 and using a makefile, allowing people to use several versions of Visual C++
Ten years experience in Windows operating systems developing in information security companies;
great team relationship; problem solving using systemic vision, knowledge bases maintenance,
chronograms and people coordination.
Software and hardware inventory
Clipboard and PrintScreen protection using windows hooks and global messages manipulation
Driver writing system event log
DeviceIoControl user/kernel communication
Desktop remote control using VNC technique
Remote execution tool PsExec (SysInternals) like
Print control using regex (Boost) and shell hook
Access policies management during user logon/logoff (register and hooks)
Datgabase migration CTree -> SQL (OLE classes)
Windows authentication using custom GINA and DCOM; Credential Provider (Vista)
CTree database synchronism using custom DCOM service
Bootable Linux CD with bash scripts and disk cryptography tools using C language
Hard disk encryption and PenDrive (USB) storage control
Blue Screen analysis using memory dumps and WinDbg live (Gflags)
System account execution using custom COM service
MBR (Master Boot Record) customization library
Blowfish/SHA-1 encryption library using C++ and 16 bits Assembly
Log access driver using shared memory between user and kernel mode
Kernel mode API hook for 9X and NT platforms
16 bits Assembly loader; debugging using debug.com tool
Executable protection using embedded domain authentication recorded inside files resources
Internet Explorer 6/7 and Firefox 1/2 browsing protection using Assembly 32 bits code injection
Code, strings and execution protection library (using Win32 interruptions)
Centralized log generation library using shared memory and global events
Internet Explorer 6/7 BHO (Broser Helper Object) and ActiveX; Mozilla/Firefox XPI plugin
Projects management using Source Safe, Bazaar and Batch (Win) scripts
Kernel mode debugging using SoftIce and WinDbg for NT