 Hey everybody, this is Brian, and welcome to the 104th tutorial with cute C++ and GUI programming. It's been a very, very extremely long time since I've done a video to the tune of almost I think six months, so please bear with me as I get used to doing this again. You might hear me moving my microphone around. For this tutorial, what we're going to do is mix cute with native. For this, we're going to make a keylogger in Windows. If you don't know what a keylogger is, it's when you press a key on the keyboard and this program will listen to the keystroke and then do whatever you want with it, dump it to a text file, whatever. In order to do that, you're going to need to download the Microsoft Windows SDK for Windows, whatever you're using, I'm using Windows 7. It's kind of funny. I've had a lot of people go, well, I'm not going to watch a video from somebody that uses Internet Explorer. Actually, I use Linux with Firefox. The only time I use Windows is when I'm recording these videos because I use, tada, CamStudio. The problem is I can't get CamStudio to work reliably in Linux on wine and I can't find a suitable replacement. I've had a lot of people give me feedback, but none of them work. They just, I hate to say it, they don't work. The reason why you're going to need the SDK is you need access to the headers and libraries that Windows offers. If you're a non-Windows user, I'm sorry, this tutorial will not work for you. All right. I'm using Qt Creator 214. I'm fairly certain that's recent. If not, just bear in mind there may be some compatibility issues. We're going to go File New. I'm going to make a new console application. I'm going to call this Keylogger. Now calling a Keylogger might not be the best thing in the world if you have a virus scanning program because it might just see that and get all mad. We are not writing a virus. I have to put that disclaimer out there right now. We are writing what is called a Windows hook. You'll see very soon what I mean by that. So I'm just going to hide this. And now we've got some screen real estate here. We've got our basic console program. Let's just give it the old one, two, let it compile and run so we get that garbage out of the way. And there's our just basic program. Now the premise of this is we're going to make it output on the screen in this little DOS window here. And we're going to do that when we are, when we bring notepad, so like if I type in notepad, you'll see it in our window over here. Let me reiterate that. When we type in another application, we will get the output in our application. That is called a Windows hook. The way Windows works is whenever you do anything, it sends a message to all Windows. And you can subscribe to those messages by a hook, saying I want to be notified every time there's a keystroke, a mouse movement, a registry access, et cetera, et cetera. So that's what we're going to be doing today, boys and girls. Let me kill that. No, I don't want to save that rubbish. All right, now onward and upward. As I said, it has been a long, long time. So bear with me here. First thing we're going to do is get our includes out of the way. We're going to go include, queue to bug, and let's say here include, I'm going off my notes here. I actually wrote this program and tested it earlier. From your guys' feedback, you have told me this is the best way. You don't like it when I just give you a program. So I've actually written and tested this thing and now we're going to implement it. And we're going to do include the standard IO stream because we are going to be working with some just raw C++ here. And we want to, and this is why you need the SDK, Windows, Windows.h. If you've ever done any programming with Microsoft, you know Windows.h inside now. Then we want to add a pragma comment. This is very important here. This is just saying we're using this library user32.dll, I'm sorry, .lib. And this should be part of the SDK. If you've ever done any work with Windows before, you know what I'm talking about. Now what we need to do at this point is save our work and give it a good build. If it flips out and dies, that means you are missing something most likely the SDK. We got a successful build. We can run our application. That means all of our includes all the paths and everything are in the correct spot. Now I'm not going to cover that because he's setting up environmental variables and et cetera et cetera can get kind of tedious. If you don't know how to do any of that, chances are you need to open Google and start typing because it's not easy. It's not hard. It's just not what we're going to cover today. Now we need to make a global variable called hhook. And this is just our hook. We're going to need a Windows hook. We're going to be using namespace. We're going to use the standard namespace. Now let's go into the guts of our little application here. Let me scroll down my notes. As you see, we've got just a standard Qt application. We've got our main. We've got our QCore application and then we're just exacting the application. So it's just running. Exact is just an application loop. That's why when you run your application, let me build it and run here, it doesn't just open and close immediately like a traditional DOS-based application because we're in a loop. This is one of Qt's message loops, or I should say application loops. So what we need to do now is actually set up our Windows hook. So we're going to say hhook, let me find it here, equal. And this is where Windows programming becomes just mind-numbingly infuriating. We use what's called an API or application programming interface. We're working with the raw Windows application or API. So we want setWindowsHook EX and that, you guessed it, is within Windows.h. Now what this does is it allows us to set a Windows hook. Now we need to tell it what type of hook. So we need to wh keyboard. So we're saying we're watching the keyboard. And now we need to give it the address of our proc or our Windows hook. And we're just going to call this my low-level keyboard and we want our pointer and if you want to know what these values are just go out to the Windows site that explains all this. Just Google Microsoft setWindowsHook EX and it'll show you. I wish Microsoft's documentation was better but it's actually very, very horrible. We're going to say if, hhook. And we're just testing here to say if it's null then, well, we snapped food something. We didn't get our hook. And we're just going to do our Qtabug. So we know what's going on out in the Qt world here. Hook failed. Now we would know our hook failed. So if we examine this, what we're doing here is we've got our return value, hhook, which is a hook, which is just a type def, Microsoft loves type defs. And if you hover over that, yep, it just says it's a pointer to, et cetera, et cetera. And we're calling setWindowsHook, we're saying we want to do a Windows keyboard. My low-level keyboard proc. What is that? Well, that is our callback. So we have to actually make a function with that name. So lrresults, oops, callback, and this is where it gets kind of snappy. I say snappy instead of curse words because, well, you know, don't know how old people are watching this. You've got to understand what is going on with this call. And the problem with the setWindowsHook ex is that it returns different values based on the types of things you're monitoring. So we'll do wparam and lparam. And once again, if you have no idea what these are, you'll have to go out and Google it. Actually, let me pause this and Google it real quick. All right, going out to Google, we just type in setWindowsHook ex, and you can see in the MSDN, our Microsoft Developer Network, installs an application to find hook procedure into a hook chain. Let's just go out here and take a look at this real quick here. And this is our structure here, actually not our structure, the API we're calling setWindowsHook ex, and you can see how we've got an ID hook and blah, blah, blah. Don't get hung up on these names. This really throws people off when they start on native programming, especially Microsoft, because some of these names make no sense whatsoever. But they give you details about what these are. Like the ID hook is an int type, what type, and then it says the types. These are all the hooks that you can install. You can do this shell, system manager, mouse, keyboard, et cetera, et cetera. And then you've got your hinstans, dword, dah, dah, dah, dah. And it just, I mean, on and on and on. Really, you gain some respect for what is going on under the hood just when you hit a key on the keyboard. There's so much going on under there. So take a moment, go out and read some of that. Get familiar with it. There's tons and tons and tons of examples out on the internet. Now before we go any further, what I want to do here is just give it a good build. Make sure we got everything up to snuff, because I'd hate to get, let's see, must return a value. Well, shoot. That's right. If you read the documentation, which admittedly I have not read it in a while, you need to do what's called next hook, because it'll actually stop and wait for you to say, OK, I'm done with it. Dah, dah, dah, dah, dah, dah. Sorry, I'm humming to myself. I'm usually listening to music when I write code for my personal amusement. So I'm used to just kind of humming along, being a happy little programmer. All right. So now what we're doing, and let me close this humongous thing, is we are saying, install the hook. If h hook, our return value equal null, then we failed to get the hook. Otherwise, Windows will actually call my low-level keyboard proc, or whatever you name this, every time your filter, your keyboard filter, is hit. So every time we hit a key on the keyboard, it'll call this hook. Now we have to return a value, an L result, using another API call, call next, I misspelled that, that would have been horribly bad, call next hook ex. What that does is there is a queue of items, and this will just call the next one. Returns nothing if there's nothing there. Let's give this a good build. All right. So just for measures here, we'll go key, queue to bug, and we're just going to say, key pressed. Told you it's been a while since I've done a video, bear with me. This is probably going to be like a three hour long video just because I keep screwing things up. So let's give this a good run. Hook failed. What did I do wrong here? You see when I hit the key on the keyboard, nothing happens. Let me pause this and review because sometimes figuring this out may take a while. So let me figure out what I did wrong here. OK, I see the problem. I'm calling WH keyboard, and we actually need drumroll, LL, a different filter. This is why working with Microsoft or all APIs is just maddening. Once you get into it, it makes sense. But if you're just new to it, you're like, what in the world does this mean? So let's give this a good build and run, and this thing should work now. Key pressed, key pressed. Now that looks good and dandy. Let me actually fire up notepad here. Yeah, as I'm typing notepad, you can see. Now we've actually got notepad in focus here. When I hit a key, you should see down here, key pressed. See? Works. So we have our Windows Hook installed. Now what we want to do is actually get the raw key. Figure out what key did I just type. Let's close our little application here, and I'm just going to leave this open. And this is where, yep, you guessed it, that code is going to get messy. Microsoft, of course, makes nothing easy. We have to work with quality structure. If you've done any C++ or if you've read, if you're a good little doobie and you read your C++ in 21 Days book, you know what a structure is. Well, we have to start working with those. So what we need to do is get the key information. And we do that with the keyboard, DOL, Hook struct. And we're just going to call it C key. And the pointer of the Lparam. And we need to cast that. And I know there's a better way of doing this, but just for quickness. Well, doesn't that look special? All right. So what we're doing is we're getting a pointer to the keyboard Hook struct out of the Lparam argument. When we do a Windows Hook, it has these arguments, Wparam and Lparam. Wparam is like the Windows message, whether it's key up, key down, et cetera, et cetera. Lparam is the actual key information. Let me actually copy and paste this from my notes here. So Wparam is the message. You're going to get a message when there's a key up or a key down. And when there's a system key down or a system key up, where Lparam is the actual key that was pressed. So when you see this key pressed, we're actually getting two of these. One down, one up. Now, what we need to do is make a buffer. So we're going to say W care, T buffer. And let's just do five. What do we need that for? Well, we're going to grab the key information. But we're going to get a little snazzy. So if we hit the tab key instead of character nine, we want to actually see TAB, the word tab. Now, we're going to have to grab the keyboard state. And we use another type called byte. I kind of love Microsoft. You know, I almost wonder sometimes if there's like a big whiteboard in a break room at Microsoft somewhere that has all the different type defs that they use because some of these are just, I think it's like every programmer they hire has to make their own type def. So there's like a million type defs going on in Windows. But I'm not going to argue with them. They obviously know what they're doing. They're a multi-billion dollar company. And we want to get keyboard state. I cannot spell today. Now, what get keyboard state does? Make sure I actually spelled that right. All right, what get keyboard state does is it actually gets the state for all of the keys on your keyboard. Yes. So what we're going to do here, let's review. I know I'm typing in a lot of stuff that looks like ancient Egyptian algebra. We've got our low level keyboard hook. It's a keyboard hook because we're saying WH keyboard LL. When our Windows hook is triggered, Windows will call our function. Notice that's a callback. And it'll give us code. It'll give us what type of callback it is and the actual information in the L-param. And then we have to get that structure out of memory. Now we have to have a buffer because we're going to fill that buffer up with information. And then we're going to get the keyboard state of every key on the keyboard. Why are we doing that? Because we want to know the different states of the key, whether they are like the shift key, the alt key, because you may do like, you know, shift A for capital A. So you want to know the actual state of the keyboard. So to do that, we need to make yet another function. Avoid, update, key state. I have been gaming, so I cannot type. I honestly think that if you play games, you can't type because you're used to using short hands. If you're wondering what I've been playing while I'm sitting here typing all this gibberish out, I've been playing Diablo 3 and Starcraft 2. I have not been playing nearly as much as I wish I could. Actually, right after I make this video, I think I'm going to log into Battle.net and start playing. So we'll take our key state here. We'll do our key code, right? And then we are going to say, get key state for the key code. So what we're doing essentially is we have our keyboard state. We have an array, 256 items of bytes. And we're going to take that and say, get the item at key code, and then update it by using the get key state. Pretty simple, huh? Now, why are we doing that? Well, the answer is both complex and simple. We're doing it because we have to get the keyboard state of all the keys on the keyboard so that we know whether, like I said, Shift-Ctrl-Alt are pressed. And then we have to actually go out and update those individual items. It's kind of flaky the way Microsoft does this. Maybe I'm doing it dead wrong. I don't know, but let's give it a good build at this point. Make sure we don't have any little bugs creeping up into our code here. Got a couple of warnings, nothing to worry about. Everything should be good to this point. Now, let's call update key state. This is going to look a little, what's the word I'm looking for, hokey. So I have to apologize. Keyboard state. And we want the, and Windows are called virtual keys or vk shift. So we want to know the shift key state. And let's just do a little copy and paste magics. You know, do a couple of these. We want to know virtual key capital or the caps lock. We want to know the vk control or the alt key. Is that control or is, no, that's control key. I'm sorry, vk and then the menu key, which is actually the alt key. Very intuitive, isn't it? Thank you, Microsoft. Now we're going to get the keyboard layout. Now, why are we getting the keyboard layout? We're getting the keyboard layout because your keyboard may be laid out different than mine, depending on where region, what country, what language you're actually using. So Microsoft allows for different keyboard layouts just to add to the complexity here. So we'll call keyboard layout equal. You guessed it, keyboard layout. And we're going to get the first layout. That's why we had that zero in there. Now we want to get the name. And we want a L-P-S-Z. We're going to call that L-P-S-Z-S name. Just copy and paste it, make sure I got it right. Yep, okay. And this is going to be, okay, got 100. Now I'm going to copy and paste a little section of code here. This guy right here looks like what we're doing is a little bit of black magic. And you're right, it is. We're doing, I think it's called a bit register shift or a bit shift. No, forgive me, I don't really know. What it is is Microsoft has a specific way of laying all this out in memory. So you have to shift it by a number of items. So you have to shift the flags by 24 and scan code by 16. To understand the difference between a flag and a scan code, go read Microsoft's documentation because you will just, I guarantee you're going to sit back and go, what? What in the world? I don't think they could have engineered this any more difficult. But I'm sure with other operating systems it's just as difficult. Now int I equal, this is where we're going to get the name of the key that we just pressed. Get key, name, text. What we're going to do here is we're going to get, how if I actually spelled the API name right? Get key, name, text. We're going to say, okay, I want to know what the name of that key is. So we're going to take our D, MSG. We're going to cast to L, P, T, S, T, R which is a string type in Windows. We're going to take our name here. And our buffer size of course is 255. Now, that was a lot of typing. What have we accomplished so far? Not a whole lot, but let's review super quick. I want to kind of review as we go. We've got our Windows hook. We've got our key state where it's got an array and it'll update different items. We're getting the keyboard structure. We've got a buffer here. We get the keyboard state for every key in the keyboard. And then we update individual states for the shift, capital, control, and alt. And then we get the keyboard layout. And then we do a little bit of Microsoft black magic here. And then we get the key name. So if I press the tab key, it'll be character nine. But we wanted to actually say TAB for tab. Pretty snazzy, huh? Now, what we're going to do is try to convert the key info. Because now that we've got all this awesome stuff, we need to actually convert it into something. We want to convert it into Unicode. So we've got our C key and we want our VK code or virtual key code, our C key. And then we want our scan code. And then we start, you guessed it, keyboard state, our buffer. Notice we haven't really done anything with the buffer because this is what the buffer is for. Let me actually scroll over in my notes. This is one long, long line here. And I promise you we will review after we get all this done and working. And we get our keyboard layout. Now, some of you C++ gurus out there go, well, Brian, you could have done most of that in here. Yes, we could have, but I wanted to really break it out so it made sense. What we're doing here is we're just converting that to Unicode and getting a result. Now, because this is Windows, actually I shouldn't say Windows because this is C++, what we want to do here is say at the fourth position or the last position in our buffer, we want to actually add a zero care. This goes back to that chapter you probably skipped in your introduction to C++ book, which is that strings are null terminated, meaning the last part of a string will have a character zero. Without that character zero, it's not a real string. So we need to convert it into an actual string here. And finally, print the output. And we're gonna do a Qtabug and we're just gonna say key, see key code, I'm sorry, vkey. Virtual key code, there we go. And then we need to do a little bit of black magic here. We're gonna do a Q string from UTF16. Let me kind of scroll over here. Now, what are we doing here? Well, we're actually converting it from a UTF16. And we have to cast it again. Use short, pointer to our buffer. I'm sorry, if you can hear my cat, I'm invisible to these cats until I sit down to do something and then suddenly they love me. Now, why are we doing this? Let's back up real quick. Why are we doing this Q string from UTF16, U short, pointer, buffer? Because the buffer is a different type than a Q string. So we actually have to convert that buffer to U short and then cast it from that into a Q string using the from UTF16. Ooh, that's a mouthful. But that's the beauty of Qt is that you can do these sort of things. Now, save us a little bit of issues here. Hold on, kitty needs my attention. Sorry about that. Cat is incredibly like 20 years old, so let's do this. Let's just do a little copy and paste magic here. And we're going to do that LPSC name, that funky variable that we did. All right, that is a lot of typing. It looks to actually get rid of this Qt bug right there. Now, if we've done everything correctly, this should just work. Let's compile and run. All right. Let's actually press key. All right, now you see how you get two. That's because of the key down and the key up. Let's actually grab notepad here. Oh, see, there you go. As you can see, we're typing in notepad, but our program actually has a Windows hook. And we have our key, and there is the actual key number, like the backspace is key eight, whereas like the letter H is 72. And then when I hit the backspace, instead of just doing eight, it actually printed out backspace. So let me hit tab, see, LOL. There you go. Once again, why is it printing out two Ls when I only typed it in once? Well, that's because you got a key down and a key up. So you can very easily filter that out in your code by saying if, you know, WM key down, let me go back in here. You know, if WPram is WM key down, then do this. And that's boys and girls. That is the foundation of a Windows key logger. What would you do with this information? Hmm, well, I know some of you out there probably going, well, I could make a key logger and record what my boyfriend, girlfriend, or my kid, or my uncle, or my neighbor is doing. Yes, you can, but that would be illegal, depending on what country you live in and whether or not you own the computer and all these other sorts of legalities. So this video comes with a disclaimer of I'm not responsible for anything you do with this information, et cetera, et cetera. I'm not gonna show you how to dump this into a text file, but I think if you know cute enough that you're following this video, you can figure that part out on your own. Other things you could do is like a global hotkey. Like, you know, some programs like, you take, what's that program called? Snagit, hit print screen, and instead of just copying the screen to the clipboard, it opens up Snagit and lets you do whatever you want to it. That's, you know, essentially a Windows global hotkey. And there are other ways of registering a hotkey, but I wanted to really show you the raw, gritty, hard way of doing a Windows system hook and what's installed. So let's, let's review. All right, we've got our includes and we have Windows H. If you put Windows H in there and you go to build it and it says, no go, Charlie. Well, that means that you can see in that little tooltip it's Windows, Microsoft SDK, Windows version six, blah, blah, blah, blah. If you don't have the Windows tool, Windows SDK installed, no luck. You're not gonna get that. You can install the Windows SDK separately or you can, like I have Visual Studio installed so that's probably how I got it. We're including IO stream. We're also doing this pragma comment lib meaning we're using the user 32 lib which is part of the SDK without that. Nothing will work. We have a global variable called H hook which if you go down into your main argument, there it is in all its beauty. We're doing a Windows hook EX telling you we want to monitor our keyboard. And this is a low level hook by the way. It doesn't get much closer to the bare metal than this. And then null zero. And then if our hook failed, what are some reasons the hook could fail? Well, as you saw, I botched up our filter. Also certain antiviral programs will not allow a global keyboard hook whatsoever because these things are extremely dangerous. Yes, these work even when the program's not visibly running. You can write a Windows service and have this run in the background snagging key input. It's tricky, but it can be done. Typically Microsoft says you have to do a key logger inside of a DLL. Well, as you can see, we just did a console application and it's running just fine. The keyboard hook uses a callback. Here's our callback. My low-level keyboard proc, probably the longest name in the world. And that has a code, a WPram and an LPram. Once again, go out to the web and look all this information up. You should really, you know, instead of just copying and pasting what I did and using it, you should really learn this insight now if you really wanna use it. We're getting our pointer to our structure. We're making a buffer. That buffer's gonna be filled later. We get the keyboard state for all the keys on the keyboard and then we update the state for specific keys. Get the keyboard layout, whether it's in United States or Hungarian or I don't know the names of the keyboard layouts. Forgive me. And then we are getting our name. Actually, we're registering space for the name. And then we're doing a little bit of Microsoft magic with bit shifting. And then we actually get the key name. This is where we do, like if you hit the backspace, it says backspace instead of just, what is it, character eight. And then we try to convert the key info into Unicode. We're doing Unicode because, well, Windows seven is all Unicode now. And then of course we print it out onto the screen and we're doing our key code, which is actually the byte number. So like tab is nine and the inner key is actually like, what is it, 12, 13, character turn line feed. And things like that. If you're on a Linux system, this obviously won't run. And then we take our buffer, cast it to a U short and then do a from UTF 16 into a Q string. Poof. Same thing with our name. And that's how we get our key output. And then last but certainly not least, we have to return a value of call next hook EX, which is a Windows API call. All in all, this is our tutorial. This is Brian. Thank you for watching. I hope you found this tutorial education entertaining and I have to apologize. It's been, oh my gosh, six plus months since I've done a tutorial. I've been so busy. Yeah, I posted a video saying back, the reasons why I haven't been keeping up with my website or feedback and life has just been crazy but I really wanna get back into tutorials. So this was my first attempt at getting back. Thank you for watching. I hope you found this educational and entertaining and if you, actually let me pause it and bring up my website super quick. You can always find this video out on my YouTube channel or on my website voidrealms.com where I have under tutorials, I have all the categories like cute and then I have them all categorized and you can click it and the accompanying source code will be with the tutorial. So have fun and happy coding.