0

I've recently realized that Python's pynput module's key click doesn't get registered in certain software. However, physical key clicks work perfectly fine. This raises the question of how are the two different methods been recognized. I thought this would've been an answered question from a long time ago but I can't seem to find any post about this.

Let's take a random game such as Genshin for example. The "w" key on the keyboard would result in the character in the game moving forward. However, a program such as the following that "holds" down the "w" key doesn't get registered by the game.

from pynput.keyboard import Key, Controller

keyboard = Controller()

while True:
    keyboard.press("w")
    keyboard.release("w")

The two big questions that I have are:

  1. What is the difference between physical key clicks and the program generate key clicks that allowed these softwares to distinguish which method is used?
  2. Based on the answer to the first question, is there a way to bypass such a difference without tempering with the software's code (aka disguise program generated key clicks as physical key clicks)?

Thanks in advance!

Edit: If anyone has any idea on how this works, please let me know. Any help would be much appreciated!

Haru Frost
  • 237
  • 1
  • 12
  • Perhaps if you held the key down for a non-zero length of time, you'd actually see some forward movement... – jasonharper Nov 28 '21 at 03:03
  • @jasonharper It works the same even if it's held down. I don't think the key clicks get registered in the first place – Haru Frost Nov 30 '21 at 04:01

2 Answers2

2

I also encountered this problem when I was trying to write a small program to help myself in Genshin. After an excruciating search, I found these two questions: question1, question2

I'm not very sure how it exactly works, so I can only give you my conclusion: When we run Genshin, we give it admin rights. Programs without admin rights sort of can't interact with it.

To solve this problem, you can merge this into your code:

import ctypes, sys

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if is_admin():
    # Code of your program here
else:
    # Re-run the program with admin rights
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)

Then you need to make the code an executable with pyinstaller module. When you execute it, it will re-run and ask you for admin rights, then it can do its job on Genshin or other program.

Oatmeal
  • 19
  • 3
  • This is a very interesting take. I haven't figured out a solution to this problem ever since I posted this question. I'll try this a bit later and see how it works. – Haru Frost Nov 30 '21 at 04:02
1

There are certainly games that intentionally try to prevent the kind of cheating you're trying to do. How they do so depends on the operating system.

pynput on Windows, for example, uses the send_input API to inject keystrokes into the input system, but a sufficiently motivated application could be reading at a lower level, by using a keyboard filter driver to pull keystrokes before they get into the input system.

With such a design, there's nothing you can do in user mode to cheat the keys. You would need your own kernel driver, and even then it's not trivial to guarantee the order that the filters load.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30