From fd762b1b80976f9cf656a0fb510738a1de10389a Mon Sep 17 00:00:00 2001 From: retoor Date: Sun, 22 Dec 2024 08:06:49 +0100 Subject: [PATCH] Progress. --- plot.py | 200 +++++++++++++++++++++++++++++++++++++++++++----------- review.md | 36 ++++++++++ 2 files changed, 195 insertions(+), 41 deletions(-) create mode 100644 review.md diff --git a/plot.py b/plot.py index 65112ef..ebeb22e 100644 --- a/plot.py +++ b/plot.py @@ -1,21 +1,66 @@ import sqlite3 +import time +import matplotlib.pyplot as plt +import pathlib +from xmlrpc.client import ServerProxy + +api = ServerProxy("https://api.molodetz.nl/rpc") connection = sqlite3.connect('tikker.db') -def render_per_hour(): + +weekday_sql = ( + "CASE " + "WHEN strftime('%w', timestamp) = '0' THEN 'Sunday' " + "WHEN strftime('%w', timestamp) = '1' THEN 'Monday' " + "WHEN strftime('%w', timestamp) = '2' THEN 'Tuesday' " + "WHEN strftime('%w', timestamp) = '3' THEN 'Wednesday' " + "WHEN strftime('%w', timestamp) = '4' THEN 'Thursday' " + "WHEN strftime('%w', timestamp) = '5' THEN 'Friday' " + "WHEN strftime('%w', timestamp) = '6' THEN 'Saturday' " + "END" +) + +def query(sql): + start = time.time() + cursor = connection.cursor() + print(sql) + result = cursor.execute(sql).fetchall() - cursor.execute("SELECT count(0) as total, strftime('%H',timestamp) as hour FROM kevent WHERE event = 'PRESSED' GROUP BY hour ORDEr BY hour") - rows_presses = cursor.fetchall() + cursor.close() + duration = time.time() - start - cursor.execute("SELECT count(0) as total, strftime('%H',timestamp) as hour FROM kevent WHERE event = 'REPEATED' GROUP BY hour ORDEr BY hour") - rows_repeated = cursor.fetchall() + print("Duration: {}\n".format(duration)) + return result +def render_per_hour(week): + week = f"'{week}'" - cursor.execute("SELECT count(0) as total, strftime('%H',timestamp) as hour FROM kevent WHERE event = 'RELEASED' GROUP BY hour ORDEr BY hour") - rows_released = cursor.fetchall() + sql_presses = ( + "SELECT count(0) as total, strftime('%H', timestamp) as hour, " + "strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'PRESSED' AND week = {week} " + "GROUP BY week, hour ORDER BY hour" + ) + + sql_repeated = ( + "SELECT count(0) as total, strftime('%H', timestamp) as hour, " + "strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'REPEATED' AND week = {week} " + "GROUP BY week, hour ORDER BY hour" + ) - import matplotlib.pyplot as plt + sql_released = ( + "SELECT count(0) as total, strftime('%H', timestamp) as hour, " + "strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'RELEASED' AND week = {week} " + "GROUP BY week, hour ORDER BY hour" + ) + + rows_presses = query(sql_presses.format(week=week)) + rows_repeated = query(sql_repeated.format(week=week)) + rows_released = query(sql_released.format(week=week)) totals = [row[0] for row in rows_presses] hours = [row[1] for row in rows_presses] @@ -27,66 +72,139 @@ def render_per_hour(): hours_released = [row[1] for row in rows_released] plt.figure(figsize=(8, 6)) - plt.plot(hours_repeated, totals_repeated, marker='o', label='Repeats per hour', color='green') plt.plot(hours_released, totals_released, marker='o', label='Releases per hour', color='orange') + plt.plot(hours, totals, marker='o', label=f'Presses per hour week {week}', color='red') - plt.plot(hours, totals, marker='o', label='Presses per hour', color='red') plt.xlabel('Hour') plt.ylabel('Event count') plt.title('Keyboard events') plt.legend() - plt.grid(True) - plt.show() -def render_per_weekday(): - cursor = connection.cursor() + plt.savefig(f"graph_week_{week.strip("'")}_per_hour.png") - weekday_sql = """ CASE - WHEN strftime("%w",timestamp) = 0 THEN 'Sunday' - WHEN strftime("%w",timestamp) = 1 THEN 'Monday' - WHEN strftime("%w",timestamp) = 2 THEN 'Tuesday' - WHEN strftime("%w",timestamp) = 3 THEN 'Wednesday' - WHEN strftime("%w",timestamp) = 4 THEN 'Thursday' - WHEN strftime("%w",timestamp) = 5 THEN 'Friday' - WHEN strftime("%w",timestamp) = 6 THEN 'Saturday' - END """ +def render_per_weekday(week): + week = f"'{week}'" - cursor.execute(f"SELECT count(0) as total, {weekday_sql} as weekday, strftime('%w',timestamp) as hour FROM kevent WHERE event = 'PRESSED' GROUP BY hour ORDEr BY hour") - rows_presses = cursor.fetchall() + - cursor.execute(f"SELECT count(0) as total, {weekday_sql} as weekday, strftime('%w',timestamp) as hour FROM kevent WHERE event = 'REPEATED' GROUP BY hour ORDEr BY hour") - rows_repeated = cursor.fetchall() + sql_presses = ( + f"SELECT count(0) as total, {weekday_sql} as weekday, " + "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'PRESSED' AND week = {week} " + "GROUP BY week, day ORDER BY day" + ) + sql_repeated = ( + f"SELECT count(0) as total, {weekday_sql} as weekday, " + "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'REPEATED' AND week = {week} " + "GROUP BY week, day ORDER BY day" + ) - cursor.execute(f"SELECT count(0) as total, {weekday_sql} as weekday, strftime('%w',timestamp) as hour FROM kevent WHERE event = 'RELEASED' GROUP BY hour ORDEr BY hour") - rows_released = cursor.fetchall() + sql_released = ( + f"SELECT count(0) as total, {weekday_sql} as weekday, " + "strftime('%w', timestamp) as day, strftime('%U', timestamp) as week " + "FROM kevent WHERE event = 'RELEASED' AND week = {week} " + "GROUP BY week, day ORDER BY day" + ) - import matplotlib.pyplot as plt + rows_presses = query(sql_presses.format(week=week)) + rows_repeated = query(sql_repeated.format(week=week)) + rows_released = query(sql_released.format(week=week)) totals = [row[0] for row in rows_presses] - hours = [row[2] for row in rows_presses] + days = [row[2] for row in rows_presses] totals_repeated = [row[0] for row in rows_repeated] - hours_repeated = [row[2] for row in rows_repeated] + days_repeated = [row[2] for row in rows_repeated] totals_released = [row[0] for row in rows_released] - hours_released = [row[2] for row in rows_released] + days_released = [row[2] for row in rows_released] plt.figure(figsize=(8, 6)) + plt.plot(days_repeated, totals_repeated, marker='o', label='Repeats per weekday', color='green') + plt.plot(days_released, totals_released, marker='o', label='Releases per weekday', color='orange') + plt.plot(days, totals, marker='o', label=f'Presses per weekday week {week}', color='red') - plt.plot(hours_repeated, totals_repeated, marker='o', label='Repeats per weekday', color='green') - plt.plot(hours_released, totals_released, marker='o', label='Releases per weekday', color='orange') - - plt.plot(hours, totals, marker='o', label='Presses per weekday', color='red') plt.xlabel('Day of week (0 = Sunday, 6 = Saturday)') plt.ylabel('Event count') plt.title('Keyboard events') plt.legend() - plt.grid(True) - plt.show() -render_per_hour() -render_per_weekday() + plt.savefig(f"graph_week_{week.strip("'")}_per_weekday.png") + +def get_weeks(): + sql = "SELECT strftime('%U', timestamp) as week FROM kevent GROUP BY week" + weeks = query(sql) + return [record[0] for record in weeks] + +def get_score_per_week(): + sql = ( + "SELECT strftime('%U', timestamp) as week, event, COUNT(0) as total " + "FROM kevent GROUP BY event, week" + ) + return query(sql) + +def get_score_per_day(): + + sql ="SELECT count(0) as total, CASE WHEN strftime('%w', timestamp) = 0 THEN 'Sunday' WHEN strftime('%w', timestamp) = 1 THEN 'Monday' WHEN strftime('%w', timestamp) = 2 THEN 'Tuesday' WHEN strftime('%w', timestamp) = 3 THEN 'Wednesday' WHEN strftime('%w', timestamp) = 4 THEN 'Thursday' WHEN strftime('%w', timestamp) = 5 THEN 'Friday' WHEN strftime('%w', timestamp) = 6 THEN 'Saturday' END as weekday, strftime('%w', timestamp) as day, strftime('%U', timestamp) as week FROM kevent WHERE event = 'REPEATED' AND week = '50' GROUP BY week, day ORDER BY day" + + sql = ( + f"SELECT strftime('%U',timestamp) as week, {weekday_sql} as wday, event, COUNT(0) as total " + f"FROM kevent WHERE event in ('PRESSED') GROUP BY week, event, wday ORDER BY week, event, wday" + ) + return query(sql) + +def get_totals(): + sql = "SELECT count(0) as total, event from kevent group by event" + return query(sql) + +# Main execution +if __name__ == "__main__": + time_start = time.time() + + for week in get_weeks(): + render_per_hour(week) + render_per_weekday(week) + + print("Score per week:") + for record in get_score_per_week(): + print(f"{record[0]} \t{record[1]} \t{record[2]}") + + print("Score per day:") + for record in get_score_per_day(): + print(f"{record[0]} \t{record[1]} \t{record[2]}") + + print("Total events:") + totals = 0 + for record in get_totals(): + print(f"{record[1]}: {record[0]}") + totals += record[0] + print(totals) + + result = {} + rows = query("SElECT strftime('%Y-%m-%d', timestamp) as day, GROUP_CONCAT(char,'') FROM kevent WHERE event = 'PRESSED' group by day") + for row in rows: + result[row[0]] = row[1] + + with open("keylog.txt","w") as f: + for day in result.keys(): + with open("logs_plain/"+day+".txt","w") as g: + g.write(f"**{day}**: ```{result[day]}```\n\n") + f.write(f"**{day}**: ```{result[day]}```\n\n") + for file in pathlib.Path(".").glob("logs_plain/*.txt"): + print("Working on: {}".format(file)) + dest_file = file.parent.parent.joinpath("logs_summaries").joinpath(file.name) + print("Dest file: ", dest_file) + with dest_file.open("w+") as f: + print("Requesting...") + response = api.gpt4o("The following data is from my keylogger, make a summary of what i did: ```"+file.read_text().replace("@","").replace("`","")+"```") + print("Done") + f.write(response) + print(response) + + + print("Duration: {}".format(time.time() - time_start)) diff --git a/review.md b/review.md new file mode 100644 index 0000000..2942bfb --- /dev/null +++ b/review.md @@ -0,0 +1,36 @@ +```markdown +# Summary of Project Reviews + +This project consists of various C and Python files primarily focused on handling keyboard input, visualizing data, and managing SDL graphics rendering. Below are primary insights from the code reviews and breakdowns: + +## Code Files + +### C Files +- **keyc3.c**: Demonstrates handling input events using XIM and XIC for X11 applications. It performs resource cleanup but lacks keyboard layout validation and error handling. +- **keyc.c**: Handles key symbols and input using `XkbKeycodeToKeysym` but has casting issues with `XLookupString` leading to potential undefined behavior. +- **keyc2.c**: Converts keycodes to characters using X11 but doesn’t fully initialize event fields, and hardcodes values may limit functionality. +- **graph2.c**: Utilizes SDL for creating an animated graph. Manages resources well but assumes SDL setup. Code organization and scaling could be optimized. +- **graph.c**: A simple SDL bar graph application that could benefit from dynamic scaling and better error handling. + +### Python Files +- **plot.py**: Analyzes keystrokes from an SQLite database and generates plots. Implements clear workflows but has security risks due to non-parameterized SQL queries. +- **zipit.py**: Compresses text files using base64 and zlib; effective but lacks error handling for file operations. + +### Other Files +- **tikker.c**: Monitors keyboard events on Linux, logging to a database. Needs better error handling and could benefit from using other event handling utilities for optimizations. + +## Common Issues Across Files +- **Error Handling**: Many files lack sufficient error handling, particularly in database operations and system calls. +- **Security**: Potential vulnerabilities in SQL handling due to non-parameterized queries. +- **Code Optimization**: Common opportunities include optimizing loops, using more efficient data structures, and improving modularization. +- **Platform Assumptions**: Assumptions in SDL and X11 setups can lead to undefined behaviors if not met. + +## General Recommendations +- **Security**: Use parameterized queries to prevent SQL injection vulnerabilities. +- **Modularization**: Break down larger functions into smaller ones for better readability and maintenance. +- **Error Handling**: Implement robust error checks, especially for system calls and IO operations. +- **Performance**: Optimize event handling to use latest utilities and data structures where applicable. + +## Grade: 6.5 +This is the average rating based on individual file reviews, reflecting both strengths in resource management and areas needing improvement in error handling and security practices. +```