Click here to Skip to main content
1,868 members
Articles / Multimedia / C++

Target Eye Revealed - Part 4 - Keyboard Capturing

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
13 Sep 2013CPOL 32K   5   2
Michael Haephrati explains how keyboard capturing should be done


This article is the fourth in a series about the Target Eye Monitoring System , developed in 2000, and since. The first article was about Target Eye's Auto Update mechanism, and how it is capable of checking for updates, downloading them when there are, installing them and running them instead of the old version currently running, all of the above, with no end-user intervention. The second article was about the Target Eye's screen capturing mechanism, and how compact JPG files are created combining a reasonable image quality and a small footprint. The third article was about the Shopping List mechanism. Well, the next significant component of the Target Eye system is Keyboard Capturing. There are several methods to implement it and many issues to be aware of, so besides the historical value that some people may find in this product, I hope to bring some technical value as well... Smile | <img src=

While writing this article I tried also to bring you other sources for Keyboard Capturing among them articles at Code Project and external sources. 

What is Target Eye

Image 2

In the image above, the Target Eye US patent application 

Target Eye Monitoring System, which I have developed on the year of 2000, was one of the first surveillance and monitoring tools for capturing activity of remote computers. Unlike hacking tools, Target Eye is a monitoring tool which was built as a product aimed to be used by Law Enforcement agencies, and specifically by people with no actual knowledge of hacking. The product is focused in the information, how to collect it, structure it, summarize and prepare it to be used as part of an ongoing investigation. Target Eye was built to run months and years without crashing, which is a very important requirement from such products as user being investigated is not supposed to do anything the entire time the software runs on his / her computer. This requirement creates a need to implement functionalities such as installation upgrades and reporting without any end user intervention whatsoever, so stability is a key factor here. QA of such products requires thousands of testing hours and to be honest, bugs always occurs and to avoid most of them it takes time, so only a mature product which was used for years can be trusted for that matter.

  • Target Eye Monitoring System has several building blocks:
  • Target Eye Secret Agent - the covert part of the product that runs on the monitored computer
  • Target Eye Operator - the authority that operates the Secret Agent (for example: a Law Enforcement agency).
  • A Mission - a request to perform an action. There are many possible actions (for example, capturing the screen, as described in an other article of mine or searching and finding files, as described in this article).
  • Target Eye Compiler - The tool that is used by the Target Eye Operator to customize a Secret Agent for performing specific tasks. 

Image 3 

Keyboard Capturing takes place by the Target Eye Secret Agent and is configured by the Target Eye Compiler

What is Keyboard Capturing

According to Oxford Dictionary, Key Logging (as know as Keyboard Capturing) is "a computer program that records every keystroke made by a computer user, especially in order to gain fraudulent access to passwords and other confidential information".

Needless to mention, there are many lawful reasons to record keystrokes (especially if you record and monitor your own PC...), from Parental Control to uses by Law Enforcement, military and Intelligence agencies against cyber crime and terror. Target Eye was invented mostly for these markets. Further, there is a difference between products that record keystrokes, referred to as "Key Loggers" and surveillance products such as Target Eye which record keystrokes among other things.

When I write a new article I check first what was already written about the topic I'm writing about, so in this case, there is an article named Basic Keystroke Mining by Alexander Kent, which brings code sample in C#. Another article about Mouse and Keyboard Hook, by Adam Roderick J which brings the traditional approach of using Global Hooks which requires a DLL (source code is in c++ and the sample application is not common to key loggers because it works like a recorder - player system. You record your events - mouse and keyboard activity and then it plays it back to you). To the best of my knowledge, the first demonstration of such idea was introduces by a friend of mine, a programmer who is now famous in the film industry, Oren Peli who programmed such application when he was 16 years old and had an Amiga computer... Another interesting article I have read is about Keyboard Hooking in Kernel by Günter Bergmann. You may also find the following article: Background Applications listening for Keyboard Activity with source code in VB.

Additional two sources I have found are: Kid Logger and SpyTool.

Kid Logger is a commercial product (a Parental Control system) by Rohos, a start-up company in Moldova which collects data about user activity on Windows based computers along with Mac or mobile phones,  and creates detailed time tracking and productivity reports available online, I am mentioning this product because full source code is included. To get the source code you need to download the trial version and install it. You will find the source code folder inside the installation folder. The source code is not the most up to date version but contains a perfect example of using Global Hooks in a DLL. Rohos, whom I work with for many years, has done amazing things in many areas related to Information Security, and obviously their source code, even though it is outdated is a state of the art when it comes to coding standards.   

SpyTool is a spyware which can not only capture the keyboard but also capture the web cam if one is attached to the monitored computer. It was developed by a college of mine, Gregory Stein, who has a full time job at Intel, and therefor has very little time to update his project. Greg was kind enough to give me permission to check the possibility of adopting some parts of his source code, especially the web cam capturing code, to be used in the current and future versions of Target Eye.  

Image 4

In the image above - how Keyboard Capturing is turned on and off (2), and how Hot Words are defined (2)

How Target Eye has evolved 

I started developing Target Eye on 2000 starting with the visual (UI) part which will be described in future articles. This part was used to display data (mostly screen capturing images) from multiple sources in a "Video Wall" style layout. The first POC was developed under Visual Basic 6.0 and here is a sample from the very first version. GetText returns the title text of a given window.  

Function GetText(hWnd) As String
    Dim GetString As String
    Dim TrimSpace$
    Dim GetTrim
    GetTrim = Sendmessagebynum(hWnd, 14, 0&, 0&)
    TrimSpace$ = Space$(GetTrim)
    GetString = SendMessageByString(hWnd, 13, GetTrim + 1, TrimSpace$)
    GetText = TrimSpace$ 
End Function 

 Few weeks later came the C++ version (Visual C++ 6.0)... 

 Image 5

In the image above, Target Eye 2000 display 6 "agents" monitored at the same time 

I then started working on the "Secret Agent" part  which was the actual engine that was transplant in the monitored computer and collected the information. Part of this agent was capturing the keyboard. From checking earlier versions JournalLogProc has changed over the years. In 2000-2004 it handled text using ToAscii() and saved each character typed immediately to the data file, which caused slowing down the monitored PC. 

BYTE kbuf[256]; 
WORD ch; 
int chcount;                      
    int IsHotWord=CheckHotWords(ch); 

The 2005 was a bit different as ToAsciiEx() was used. data was first captured to a buffer to enhance speed. GetKeyboardLayout() was used as well.  

DWORD dwCount;             
char svBuffer[256]; 
int vKey,nScan; 
DWORD idT = GetWindowThreadProcessId(destWnd, NULL);
KL = GetKeyboardLayout(idT);   

Apart of these evolves, Target Eye kept providing Keyboard Capturing without using an external DLL.  

Handling special keys 

A proper Keyboard Capturing engine should handle special keys and convert such keys or combination of keys into a user friendly data file entry. A good example would be reflecting deleted text. When text is deleted, the actual key captured will be either BACKSPACE or DEL. Target Eye displays these as [XXX] and [---], so if the data file shows: 

"I have corrected my mistac[XXX]ke" it means that while typing the "c" was deleted and replaced with "k". 

Other special keys are:  

VK_SPACE (or the SPACE key) - in more recent versions Target Eye saved captured data into a buffer and purged the buffer into the data file whenever the SPACE or ENTER keys were captured.  

RETURN / ENTER - these special keys are handled the same and converted to a new line ( '\n'). 

Arrow keys - which can be helpful understanding where exactly editing takes place (along with an indication of where the cursor is placed using the mouse).  

Function Keys - these are converted into their name. F1 will appear as "F1" and so on.... 

Here is part of the source code where some of the special keys are interpreted:

case VK_TAB:
  api_lpsz = _T("[TAB]");
case VK_LEFT:
  api_lpsz = _T("[LEFT]");
case VK_RIGHT:
  api_lpsz = _T("[RIGHT]");
case VK_UP:
  api_lpsz = _T("[UP]");
case VK_DOWN:
  api_lpsz = _T("[DOWN]");
case VK_PRIOR:
  api_lpsz = _T("[PAGE UP]");
case VK_NEXT:
  api_lpsz = _T("[PAGE DOWN]");
case VK_END:
  api_lpsz = _T("[END]");
case VK_HOME:
  api_lpsz = _T("[HOME]");

Handling Hot words

Another functionality which is usually part of Keyboard Capturing is handling Hot words. Hot words are phrases that are targeted to alert and cause another action when they are typed. For example, the operator of Target Eye might request that whenever the phrases "murder" or "kill" will be typed, a screenshot will be taken and an email alert will be sent to the operator. 

First the array of Hot Words is initialized. In the commercial product the list of Hot Words is obtained from the encrypted segment of the application which is attached to it by the Compiler. In this code sample, we just add 2 entries:

void InitHotWords()
    // This POC has hardcoded hot words, unlike the real Target Eye which uses the definitions created by the Compiler

Next, there is the part where captured text it analyzed and checked against this list. 

CheckHotWords() returns the index of the hot word found in the current buffer, or -1 if none.

inline int CheckHotWords()
    int i,result=-1;    // index of hotword found
        int Len=HotWords[i].GetLength();

The method used by Target Eye ensures that no matter where and how the hot word is typed, it is captured. For that matter you can go to Google, type "ki", then switch to notepad and type "ll" and the word "kill" will be captured. Of course that can be changed and customized.   

Methods used for Keyboard Capturing

There are several requirements from Keyboard Capturing. Typing consumes CPU, especially when typing fast. A background thread which is used to capture the text being typed consumes even more CPU which can cause slowing down the PC being monitored and slowing the response of the typing, which can be annoying to the user being monitored. Another possible problem could be keys getting lost. When it comes to a tool used for Law Enforcement and forensic purposes, losing even one keystroke is not something you can live with. Further, the data file which is created and updated along the monitoring session must be up to date and accurate at any given moment, even if for example, while typing, the PC is suddenly turned off (for example, a power failure). Keyboard Capturing must reflect the current active application and window and relate each key stroke to the correct window and application. Screenshots, which I have described in this article, should also relate to any text typed while this screen was captured.

There are several methods that can be used to record the keyboard:


The common method uses is a Global Hook created using a separate DLL. See:

HHOOK WINAPI SetWindowsHookEx(
  _In_  int</span> idHook,
  _In_  HOOKPROC lpfn,
  _In_  HINSTANCE hMod,
  _In_  DWORD dwThreadId
I have encountered several problems with this method, especially when it comes to most recent versions of Windows (i.e. Windows 7) where keystrokes get lost especially when there is high CPU activity.  


A method which is less known - using Raw Input directly from the keyboard.

BOOL WINAPI RegisterRawInputDevices(
  _In_  PCRAWINPUTDEVICE pRawInputDevices,
  _In_  UINT uiNumDevices,
  _In_  UINT cbSize 


I have chosen to use Journal hooks for Target Eye, and very few changes were made since the first release of Target Eye (on 2000) and later releases of the product. Journal Hooks are system wide hooks used mostly for recording and playing back keyboard and mouse events, however for the purpose of a surveillance system, we only need the recording mechanism, which leads to a data file where all text is stored.

That approach worked excellent these days (at least until 2007) but wouldn't work today without some adjustments which are required as since Windows Vista, WH_JOURNALRECORD type of hook requires Admin privileges, code signing along with other limitations and requirements. See: 

Handling Date and Time Stamps  

When you build a monitoring product that is supposed to be operated in various countries and remote controlled in others, you must take into consideration the time zone and not only the local time.

Target Eye used CTime class (available at MFC , ATL and WTL). 

GetGmtTm() is used to get the universal date and time which will be identical regardless of the time zone.  

In addition, the actual time zone can be displayed in the data file (Target Eye does that only for screen capturing files).   

Handling International Characters

Text is captured regardless of the active application, and for that matter you can just hit the keyboard while no application is active and the text will yet be fully recorded. Target Eye, like other similar products, keeps track of the active window at the time text was typed, which helps the operator determine the context of the text captured.  

Many key logging systems works fast and efficient but when you type another language, you still get the same Latin text in the captured text file. That is because from the point of view of the hooking mechanism, the captured keys are the same regardless of the selected language. Many PC users have a multiple (usually two) language system, which they switch using ALT+SHIFT. A good monitoring system should be able to detect the active language (keymap) selected and translate the key code of the pressed key into the correct character. For example when a Hebrew-English system is used, pressing the "A" key on the keyboard, if English selected, "a" or "A" should be captured (cased on whether SHIFT is pressed), and when Hebrew is selected, the character "ש" should be captured. The way to do so is by calling ToUnicodeEx() right after obtaining the current language selected which is done by calling GetKeyboardState().

GetKeyboardState() copies the status of the 256 virtual keys to the specified buffer.

BOOL WINAPI GetKeyboardState(_Out_  PBYTE lpKeyState);  

ToUnicodeEx() Translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters.

int WINAPI ToUnicodeEx(
  _In_      UINT wVirtKey,
  _In_      UINT wScanCode,
  _In_      const BYTE *lpKeyState,
  _Out_     LPWSTR pwszBuff,
  _In_      int cchBuff,
  _In_      UINT wFlags,
  _In_opt_  HKL dwhkl

and the entire code for handling multiple languages is:

DWORD dwMsg = p->scanCode << 16;
// Translate to actual character depending on keyboard state and layout
BYTE keyState[256];
key[0]=key[1]=key[2]=0; // reset key. Note that act_length=1 "[A]"
ToUnicodeEx(p->vkCode, p->scanCode, keyState, key, 1, p->flags,layout);

Handling Data Files  

When it comes to handling the data file generated and updated by Target Eye, unlike screen capturing which generate a separate file per each screen shot, Keyboard Capturing text is kept in a continuous file which is updated constantly. This file can become huge, and usually is reset after being sent to the operator, either via Email or by uploading it to an FTP server. 

Here is how the data file is created or updated (in case it already exists):

void CreateKBCFile()
    HANDLE g_hCapFile;
    CTime theTime=CTime::GetCurrentTime();
    CString TempFileName;
    DWORD dwBytes;
        TRACE("Can't open log file %s\n",POC_LOGFILENAME);
        TRACE("KB Capturing: Can't write to log file %s\n",POC_LOGFILENAME);

A Typical Data File  

A typical data file is shown in the example bellow (the various parts were highlighted):   

Image 6

The are several parts that are part of the data file: 

  1. Active window
  2. Text typed 
  3. Time / Date stamp 
  4. Deletion of text
  5. File name that is used to indicate operation case ID, subject ID, etc. 

Then, when such file is analyzed, it is sometime quite easy to determine user names, passwords, logon details, etc. In fact, if you self monitor your own PC, which is what I did while preparing this article, you can find out lost passwords in case you need them... 


This article was written to provide another angle of the Target Eye system, and in the case of Keyboard Capturing,  there was no point providing the source code used by the older versions of this product for the reasons I mentioned.

Michael Haephrati  CodeProject MVP 2013  

©2000-2013 Michael Haephrati and Target Eye LTD

All materials contained on this article are protected by International copyright law and may not be used, reproduced, distributed, transmitted, displayed, published or broadcast without the prior written permission given by Michael Haephrati and Target Eye LTD. You may not alter or remove any trademark, copyright or other notice from copies of the content. 


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Michael Haephrati
United States United States
Michael Haephrati, born in 1964, an entrepreneur, inventor and a musician. Haephrati worked on many ventures starting from HarmonySoft, designing Rashumon, the first Graphical Multi-lingual word processor for Amiga computer.

Worked with Amdocs and managed several software projects, among them one for the Ministry of Tourism in New Zealand. During 1995-1996 he worked as a Contractor with Apple at Cupertino. After returning to Israel, worked as a Project Manager with Top Image Systems (mostly with JCC, Nicosia), and then at a research institute made the fist steps developing the credit scoring field in Israel. He founded Target Scoring and developed a credit scoring system named ThiS, based on geographical statistical data, participating VISA CAL, Isracard, Bank Leumi and Bank Discount (Target Scoring, being the VP Business Development of a large Israeli institute).
During 2000, he founded Target Eye, and developed the first remote PC surveillance and monitoring system, named Target Eye.

Other ventures included: Data Cleansing (as part of the DataTune system which was implemented in many organizations.

Also a Code Project Member since Sunday, March 16, 2003 (10 years, 5 months)
20 Sep 2013: Best C++ article of August 2013
25 Jan 2013: Code Project - Best C++ article of December 2012
31 Dec 2012: CodeProject MVP 2013

Comments and Discussions

NewsThis article won a Code Project competition! Pin
Michael_Haephrati20-Sep-13 23:50
Michael_Haephrati20-Sep-13 23:50 
This has won the 1st prize!
GeneralMy vote of 5 Pin
Akinmade Bond14-Sep-13 8:27
professionalAkinmade Bond14-Sep-13 8:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.