-4

I have been trying to create a keylogger using data structures, and I saw this piece of code on a website.

I don't understand if the "character" is ASCII value or what? Plus why are we incrementing value of character by 32 in the last condition.

for (character = 8;character <= 222;character++)
{
    if (GetAsyncKeyState(character) == -32767)
    {
        FILE *file;
        file = fopen(FileName, "a+");
        if (file != NULL)
        {
            if ((character >= 39) && (character <= 64))
            {
                fputc(character, file);
                fclose(file);
                break;
            }
            else if ((character>64) && (character<91))
            {
                character += 32;
                fputc(character, file);
                fclose(file);
                break;
            }
            /* ... */
         }
     }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

1 Answers1

1

Following the documentation for GetAsyncKeyState, the type for character is int:

SHORT WINAPI GetAsyncKeyState(
  _In_ int vKey
)

You'll note that the return value of GetAsyncKeyState is a short, which is evidently a 16-bit signed integer value.

For the return value,

If the most significant bit is set, the key is down.

Meaning the negative bit on the SHORT will be set, or a value of -32767 will be returned if a key is down (hence whey the if-branch is entered if this is the return value; the code wants to log a keystroke).

The code for logging is pretty clear IMO, but you're wondering why the increment by 32 here:

// ...
else if ((character>64) && (character<91))
{
   character += 32;
 // ...

character even though it's an int, is actually a virtual key-code. Virtual Key codes go up to 0xFE (254)

When you look at a table for the virtual key codes, values greater than 64 and less than 91 are the letters of the English alphabet. An increment by 32 will make them lowercase characters (65 is 'A', but 97 is 'a') in ASCII. That is, the code is taking advantage of the fact that an 'A' in virtual key codes is the same as a capital 'A' character in ASCII, and then performing the lowercase conversion for ASCII before printing to file.

EDIT

There appears to be some debate as to the reasoning behind the loop: for (character = 8;character <= 222;character++)

A value of 8 in virtual key code corresponds to a backspace key, or really the start of printable characters because the first 7 (starting at 1, actually) are buttons. That's not to say that ALL characters in the range 8-222 are printable.

The value of 222 (0xDE) corresponds to VK_OEM_7:

For the US standard keyboard, the 'single-quote/double-quote' key.

In other words, pretty much the last printable keyboard character on English keyboards for virtual key codes. Clearly the logger is directed at English-speaking Windows users. The actual code probably repeatedly runs the loop asking for which key is down, and then logs it.

Community
  • 1
  • 1
AndyG
  • 39,700
  • 8
  • 109
  • 143