How to simulate Keyboard presses using LowLevelProc in c#

Im trying to create an application for a game which has a kind of Anti-Macro system. (https://www.bottersgonnabot.com/automating-skill-checks-in-dead-by-daylight-part-i/) is what im trying to recreate. Although im having trouble sending Keys using native windows calls and this LowLevelProc. Could someone give me a kickstart on how to use this LowLevelProc, maybe LowLevelProc.Invoke(params) but then what? All neccessary code is given on the website above^^. Or here the most important part which is supposed, referring to the blog, to bypass those Anti-Macro stuff:

 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelProc lpfn, IntPtr hMod, uint dwThreadId);  [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName);  private delegate IntPtr LowLevelProc(int nCode, IntPtr wParam, IntPtr lParam);  private static IntPtr HookKeyboardCallback(int nCode, IntPtr wParam, IntPtr lParam) {     return IntPtr.Zero;// CallNextHookEx(_hookID, nCode, wParam, lParam); }  private static LowLevelProc KeyboardProc = HookKeyboardCallback; private static IntPtr KeyboardHookID = IntPtr.Zero;  private static IntPtr SetKeyboardHook(LowLevelProc proc) {     using (Process curProcess = Process.GetCurrentProcess())     using (ProcessModule curModule = curProcess.MainModule)     {         return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);     } }  static void SetHooks() {     KeyboardHookID = SetKeyboardHook(KeyboardProc); } 

Edit: I also tried using the Authors AutoIt Implentation to send Keys, which is using the Native input method, although it has no effect in the game

My "native" call so far is using the AutoIt lib, which uses Sendinput api so the part Im struggling with is this quote

"I noticed that no matter how I try to emulate input (sending key, sending key to the window, using original AutoIt or my C# lib), it is completely ignored. I started to wonder how is it possible to disable fake inputs globally… Turns out that fake/injected inputs can be distinguished from real ones in LowLevelKeyboardProc callback registered by SetWindowsHookEx. Each process can add its own callback to the list and everyone will be notified when key state has been sent. Then, inside LowLevelKeyboardProc, you can check lParam flags against 0x10 to test event-injected flag and handle it as you see fit. That’s what our Canadian friends from Behaviour Interactive did to stop us from cheating.

Fortunately there is a weakness in this hooks system which we can exploit. Procs are called in reversed order to the registration order (last registered proc will be called first). It also assumes that when you are done with processing a key state you will call next callback in a list via CallNextHookEx. So… what we are gonna do is to register our own proc after Dead by Daylight registered theirs and we won’t call next hook at the end. Voilà, inputs fixed."

Add Comment
1 Answer(s)

if you want ot simulate keypress you have to use SendInput:

        [DllImport("user32.dll", SetLastError = true)]         internal static extern uint SendInput(uint num_inputs, INPUT[] inputs, int size); 

with:

    [StructLayout(LayoutKind.Sequential)]     public struct MOUSEINPUT     {         public int dx;         public int dy;         public uint mouseData;         public uint dwFlags;         public uint time;         public IntPtr dwExtraInfo;     }      [StructLayout(LayoutKind.Sequential)]     public struct KEYBDINPUT     {         public ushort wVk;         public ushort wScan;         public uint dwFlags;         public uint time;         public IntPtr dwExtraInfo;     }      [StructLayout(LayoutKind.Sequential)]     public struct HARDWAREINPUT     {         public uint uMsg;         public ushort wParamL;         public ushort wParamH;     }      [StructLayout(LayoutKind.Explicit)]     public struct INPUT     {         [FieldOffset(0)]         public int type;         [FieldOffset(4)]         public MOUSEINPUT mi;         [FieldOffset(4)]         public KEYBDINPUT ki;         [FieldOffset(4)]         public HARDWAREINPUT hi;     } 

so if lowlevel keyboard proc traps the sendinput key, you cant override . You have to modify the exe or hook the hook

Answered on July 16, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.