Spoiler: Source Code Rant:



Something that inevitably comes up after awhile is hooking game input. After you're done pasting what ever



Here's the thing:

DON'T USE SEND INPUT! DON'T USE SEND INPUT! DON'T USE SEND INPUT! DON'T USE SEND INPUT! DON'T USE SEND INPUT! Why? First of all it's a vector for detection because it synthesizes input; secondly: it doesn't change the keyboard state it simply adds to it. Also it's a garbage API that gets pasted all the time and the code is just sad look at this:



C++: // This is an array (why?) INPUT input[1]; // What part of the array are you accessing here? The segfault part? input->type = INPUT_KEYBOARD; input->ki.dwExtraInfo = 0; input->ki.time = 0; input->ki.wScan = 0; input->ki.wVk = 0x20; // this is virtual key code for SPACE key // Infinite loop nice, big fan while (1) { input->ki.dwFlags = KEYEVENTF_EXTENDEDKEY; SendInput(1, input, sizeof(input)); // Sleep lul Sleep(5); input->ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, input, sizeof(input)); // And again gotta preserve that CPU time Sleep(50); }



I'll say it again:

DON'T PASTE CODE! DON'T PASTE CODE! DON'T PASTE CODE! DON'T PASTE CODE! DON'T PASTE CODE! There's nothing wrong with pasting a little bit when you're still learning but if your code is filled with dangling pointers, incorrectly allocated variables and a bunch of other really simple errors that five minutes on a LearnCPP website can teach you, then you need to stop and spend a bit of time learning. I honestly don't understand how people can spend months copy and pasting code and still learn nothing. Do you even read the code? Try to understand it or know the difference between why your code didn't work and someone else's did? Or you just trying to get that p2c out the door as quickly as possible? What happens when it breaks how are you going to fix that? You can't debug or even understand why it does or doesn't work. Or are you simply going to post on SO and pretend like it's a school project or something? Something that inevitably comes up after awhile is hooking game input. After you're done pasting what ever ImGui code you can find on the net and fumbling your way through that you're probably after a way to manipulate the game's input and like a typical noob you're probably using SendInput.Here's the thing:Why? First of all it's a vector for detection because it synthesizes input; secondly: it doesn't change the keyboard state it simply adds to it. Also it's a garbage API that gets pasted all the time and the code is just sad look at this:Here's the thing about programming if you're using an infinite loop, Sleep and calling the same function multiple times with different parameters you code is probably inefficient. That is to say it's WRONG. You should really look and this and think to yourself: "Yeah I can do better than that". Use a loop and some arrays but anyway:I'll say it again:There's nothing wrong with pasting a little bit when you're still learning but if your code is filled with dangling pointers, incorrectly allocated variables and a bunch of other really simple errors that five minutes on a LearnCPP website can teach you, then you need to stop and spend a bit of time learning. I honestly don't understand how people can spend months copy and pasting code and still learn nothing. Do you even read the code? Try to understand it or know the difference between why your code didn't work and someone else's did? Or you just trying to get that p2c out the door as quickly as possible? What happens when it breaks how are you going to fix that? You can't debug or even understand why it does or doesn't work. Or are you simply going to post on SO and pretend like it's a school project or something?

As of 2011 Microsoft doesn't recommend using DirectInput for keyboards or mice, and has started pushing the newer XInput for Xbox 360 controllers. In Windows Vista, Windows 7 and later Windows versions, the in-built action mapping UI has been removed. DirectInput is not available for Windows Store apps. Click to expand...

C++: #define DIRECTINPUT_VERSION 0x0800 #include <dinput.h>

C++: IDirectInput8 *pDirectInput = NULL; if (DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&pDirectInput, NULL) != DI_OK) { printf("[-] Failed to acquire DirectInput handle

"); return -1; }

C++: LPDIRECTINPUTDEVICE8 lpdiKeyboard; if (pDirectInput->CreateDevice(GUID_SysKeyboard, &lpdiKeyboard, NULL) != DI_OK) { printf("[-] Unable to attach to kbd

"); pDirectInput->Release(); return -1; }

C++: // Set the data type to keyboard lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard); // We want non-exclusive access i.e sharing it with other applications lpdiKeyboard->SetCooperativeLevel(GetActiveWindow(), DISCL_NONEXCLUSIVE); // Attempt to acquire the device if (lpdiKeyboard->Acquire() == DI_OK) { printf("[+] Acquired keyboard.

Press escape to exit...

"); // Start looping and grabbing the data from the device while (1) { // Poll for new data lpdiKeyboard->Poll(); // This is how the data is returned as an array 256 bytes for each key BYTE diKeys[256] = { 0 }; // Get the state if (lpdiKeyboard->GetDeviceState(256, diKeys) == DI_OK) { // Check if the escape was pressed if (diKeys[DIK_ESCAPE] & 0x80) { break; } } // We don't need realtime access, don't flood the CPU Sleep(100); } // Unacquire the keyboard lpdiKeyboard->Unacquire(); } // Free the keyboard and device objects lpdiKeyboard->Release(); pDirectInput->Release();

C++: // Same as before lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard); lpdiKeyboard->SetCooperativeLevel(GetActiveWindow(), DISCL_NONEXCLUSIVE); // Setup config for buffered output DIPROPDWORD dipdw = { 0 }; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 10; // Attempt to switch to buffered output if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) == DI_OK) printf("[+] Buffered mode enabled for device

"); // Trip flag bool bEscape = false; // Try to acquire the keyboard if (lpdiKeyboard->Acquire() == DI_OK) { printf("[+] Acquired keyboard.

Press escape to exit...

"); while (1) { // Poll for new data lpdiKeyboard->Poll(); // We asked for 10 objects at a time DIDEVICEOBJECTDATA didod[10] = { 0 }; DWORD dwNumElements = 10; // Get the data HRESULT hr = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwNumElements, 0); if (hr == DI_OK) { // Process the keystrokes for (DWORD i = 0; i < dwNumElements; i++) { // If the escape key is down exit if (LOBYTE(didod[i].dwData) > 0 && didod[i].dwOfs == DIK_ESCAPE) { bEscape = true; break; } } } // Trip flag hit if (bEscape) break; Sleep(100); } // Give the keyboard back lpdiKeyboard->Unacquire(); } // Free objects lpdiKeyboard->Release(); pDirectInput->Release();

DirectInput has unicode support. The game can use either method (above) to retrieve data from the device.

000000014167D8D0 30 80 79 BF 3A 48 A2 4D AA 99 5D 64 ED 36 97 00 Click to expand...

Tomb Raider LegendUpdated Legacy of Kain EngineCrystal DynamicsSteamAnyway let's down to business with Tomb Raider and DInput (game chosen specifically for DInput jokes). I've really got to give the development team credit on this one the way Lara animates in this game is really good and looks and plays damn well for a remake. Also women with an English accent amirite fellas?Direct InputMicrosoft's solution for making handling input for games using DirectX easy and with high performance. I say "was" because even Microsoft has disowned DInput and encourages everyone to use alternatives.From Wikipedia:Direct Input 8 was released sometime in the 2000s I believe and hasn't been updated since then. However while Microsoft strongly recommends not using it that hasn't done anything to sway developers because damn near every game I reverse seems to still use Direct Input. I mean why fix what isn't broken I guess, developers know Microsoft can't remove it because it'll break damn near every game ever made.I find one of the best ways to attack something from a reverse engineering perspective is to attempt to code your own version of said thing. So let's write our own Direct Input application!You're going to need to linkandso add those to your additional dependencies under linker in project properties.Then we need to include the DInput.h header file while defining what version we want to use. You should check the game to be certain but it's been many a year since I've seen DirectInput7 in the wild. So it's a pretty safe bet if your game was made AFTER 2000 its most likely using DirectInput8.Now you DirectX programmers will probably feel quite comfortable with DirectInput's interface because it's pretty much identical:Create an interface to the base class:Now we can create our device:DirectInput can also handle mouse input (you need to remember this and check for it when processing data).Now in order to use our new device we need to configure some options:Pretty simple right? Well hold up that's ONE way to retrieve key data from DInput there's also another way:Okay so now that you understand the basics of how a DirectInput application acquires input we can get to the task of hooking it.If you've been doing this for awhile you're probably thinking a VTable hook and you'd be correct it's the easiest and best solution for this problem. There's just one or two things I feel I should mention:If the game was released internally it's a pretty safe bet that it's running in Unicode however you can check with x64dbg (remember to install the symbols for dinput8.dll):Put a breakpoint on DirectInput8Create:Now inspect the stack:This one:If you're on x64 the process is slightly different (I'm using Hitman 2 as an example here):The IID_IDirectInput8 variable is stored in the R8 register:In this case 14164D8D0. Goto the memory view press CTRL+G to goto that address so we can see what it's pointing at:In my case the value it points to is:Which we can compare to the DInput header file and see that:It's pointing to IID_IDirectInput8A so you need to build your project in ascii mode.