- from threading import *
- from tkinter import *
- from tkinter.filedialog import askopenfilename
- from tkinter.messagebox import showerror
- import tkinter
- import tkinter.scrolledtext
- import threading
- import os
- import sys
- import urllib.request
- import glob
- import time
- import hashlib
- import socket
- import subprocess
- # self-made
- import quarantaene
- import SystemFileScanner
- from tkinter import END
- os_name = sys.platform
- verzeichnisse = []
- files = []
- partitionen = []
- terminations = []
- #if we are using Windows OS, th file paths will be using backlask,
- #but if we are using MAC/Unix OS, the file paths will be using forward slash.
- if "win" in os_name: # gives info on OS
- if not os.path.exists("AntiVirus\\Quarantine\\"):
- os.makedirs("AntiVirus\\Quarantine\\")
- if not os.path.exists("AntiVirus\\sf\\"):
- os.makedirs("AntiVirus\\sf\\")
- if not os.path.exists("AntiVirus\\Large_Update_File\\"):
- os.makedirs("AntiVirus\\Large_Update_File")
- quarantine_folder = "AntiVirus\\Quarantine\\*"
- file_to_quarantine = "AntiVirus\\Quarantine\\"
- partitionen_folder = "AntiVirus\\sf\\sf.txt"
- links_current = "AntiVirus\\Large_Update_File\\links_current.txt"
- links_downloaded = "AntiVirus\\Large_Update_File\\links_downloaded.txt"
- large_signatures = "AntiVirus\\Large_Update_File\\signatures.txt"
- f = open(partitionen_folder, "a")
- f.close()
- f = open(links_current, "a")
- f.close()
- f = open(links_downloaded, "a")
- f.close()
- f = open(large_signatures, "a")
- f.close()
- else: #In case user is using MAC/Unix OS
- if not os.path.exists("AntiVirus//Quarantine//"):
- os.makedirs("AntiVirus//Quarantine//")
- if not os.path.exists("AntiVirus//sf//"):
- os.makedirs("AntiVirus//sf//")
- if not os.path.exists("AntiVirus//Large_Update_File//"):
- os.makedirs("AntiVirus//Large_Update_File//")
- quarantine_folder = "AntiVirus//Quarantine//*"
- file_to_quarantine = "AntiVirus//Quarantine//"
- partitionen_folder = "AntiVirus//sf//sf.txt"
- links_current = "AntiVirus//Large_Update_File//links_current.txt"
- links_downloaded = "AntiVirus//Large_Update_File//links_downloaded.txt"
- large_signatures = "AntiVirus//arge_Update_File//signatures.txt"
- f = open(partitionen_folder, "a")
- f.close()
- f = open(links_current, "a")
- f.close()
- f = open(links_downloaded, "a")
- f.close()
- f = open(large_signatures, "a")
- f.close()
- files_len = counter = 0
- main = None
- update_button = None
- scan_button = None
- fullscan_button = None
- quit_button = None
- b_delete = None
- b_delete_all = None
- b_restore = None
- b_restore_all = None
- b_add_file = None
- text_box = None
- e = None
- li = None
- rb1 = None
- rb2 = None
- method = None
- bgc = None
- fgc = None
- special = None
- special_text = None
- t_time = None
- # def clock_thread():
- # global e
- # months = ["January", "February", "March", "April", "May", "June", "Juli", "August",
- # "September", "October", "November", "December"]
- # while True:
- # string_time = "%H:%M:%S o'clock, on %d.{0}.%Y"
- # month_name = time.strftime("%B", time.localtime())
- # for i in range(len(months)):
- # if (months.index(month_name)) < 10:
- # month_name = "0" + month_name
- # break
- # string_time = string_time.format(month_name)
- # current_time = time.strftime(string_time, time.localtime())
- # e.delete(0, len(e.get()))
- # e.update()
- # e.insert(0, current_time)
- # e.update()
- # time.sleep(1)
- def ScanSystemFiles():
- global files
- global text_box
- global files_len
- text_box.insert(END, "[ * ] Scanning system for files...\n")
- text_box.see(END)
- text_box.update()
- time.sleep(3)
- text_box.see(END)
- text_box.update()
- # SystemFileScanner.partitions(partitionen_folder)
- f = open(partitionen_folder, "r")
- content = f.read()
- f.close()
- content = content.splitlines()
- files = content
- files_len = len(files)
- text_box.insert(END, "[ + ] System successfully prepared\n", 'positive')
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- def full_scan(part):
- global verzeichnisse
- global files
- global text_box
- global e
- global full_scan
- global files_len
- global lock
- global t_time
- global counter
- start = time.time()
- if part == 1: # Thread-1
- i = int(len(files)*0.125)
- tmp = 0
- if part == 2: # Thread-2
- i = int(len(files)*0.25)
- tmp = int(len(files)*0.125)
- if part == 3: # Thread-3
- i = int(len(files)*0.375)
- tmp = int(len(files)*0.25)
- if part == 4: # Thread-4
- i = int(len(files)*0.5)
- tmp = int(len(files)*0.375)
- if part == 5: # Thread-5
- i = int(len(files)*0.625)
- tmp = int(len(files)*0.5)
- if part == 6: # Thread-6
- i = int(len(files)*0.75)
- tmp = int(len(files)*0.625)
- if part == 7: # Thread-7
- i = int(len(files)*0.875)
- tmp = int(len(files)*0.75)
- if part == 8: # Thread-8
- i = int(len(files))
- tmp = int(len(files)*0.875)
- if len(files) == 0:
- return ScanSystemFiles()
- text_box.tag_config('positive', foreground="green")
- text_box.see(END)
- text_box.update()
- counter = 0
- st = 0
- while i >= tmp:
- try:
- f = open(files[i], "rb")
- file_content = f.read()
- f.close()
- except:
- continue
- ret = scan_auto(files[i])
- if ret == True:
- text_box.insert(END, "[ ! ] Program: " + files[i] +
- " might be dangerous\n", "important")
- text_box.tag_config("important", foreground="red")
- text_box.see(END)
- text_box.update()
- quarantaene.encode_base64(files[i])
- files_len -= 1
- i -= 1
- runtime = int(time.time() - start)
- text_box.insert(END, "[ + ] Scan ended after\n " +
- str(runtime/60) + " minutes.\n", "positive")
- text_box.tag_config("positive", foreground="green")
- if files_len == 0:
- full_scan["state"] = "normal"
- if len(terminations) == 0:
- text_box.insert(END, "[ +++ ] Your PC is safe" + "\n", 'important')
- else:
- text_box.insert(
- END, "[ !!! ] Found {0} Threats on your PC\n".format(len(terminations)))
- text_box.tag_config("important", background="red")
- text_box.see(END)
- text_box.update()
- def quarantine():
- global text_box
- global terminations
- global li
- global b_delete
- global b_delete_all
- global b_restore
- global b_restore_all
- global b_add_file
- k = 0
- while True:
- tmp = len(li.get(k))
- if tmp == 0:
- break
- else:
- li.delete(0, tmp)
- k += 1
- li.update()
- terminations = glob.glob(quarantine_folder)
- if terminations == []:
- text_box.insert(END, "[ + ] No files in quarantine\n", "positive")
- text_box.tag_config('positive', foreground="green")
- text_box.see(END)
- text_box.update()
- else:
- text_box.insert(END, "[ + ] Files in quarantine:\n", "positive")
- text_box.tag_config('positive', foreground="green")
- text_box.see(END)
- text_box.update()
- for i in terminations:
- text_box.insert(END, "[ * ] " + i + "\n", "info")
- text_box.tag_config("info", background="red")
- text_box.see(END)
- text_box.update()
- li.insert(END, i)
- li.update()
- b_delete_all["command"] = lambda: button_action_handler("delete_all")
- b_delete["command"] = lambda: button_action_handler("delete")
- b_restore["command"] = lambda: button_action_handler("restore")
- b_restore_all["command"] = lambda: button_action_handler("restore_all")
- b_add_file["command"] = lambda: button_action_handler("add_file")
- def delete(file, ALL): # ALL = 1 => deletes all objects in quarantine
- global li
- global text_box
- global terminations
- if len(terminations) != 0:
- if ALL == 1:
- for i in range(len(terminations)):
- os.remove(terminations[i])
- text_box.insert(END, "[ + ] Deletion successful: \n" + terminations[i] + "\n",
- "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- li.delete(0, len(terminations[i]))
- li.update()
- elif ALL == 0:
- os.remove(file)
- li.delete(ACTIVE, len(file))
- li.update()
- text_box.insert(END, "[ + ] Deletion successful:\n" +
- file + "\n", "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- terminations = glob.glob(quarantine_folder)
- for i in terminations:
- li.insert(END, i)
- li.update()
- else:
- text_box.insert(END, "[ - ] Unable to locate any files\n", "negative")
- text_box.tag_config("negative", foreground="red")
- text_box.see(END)
- text_box.update()
- def restore(file, ALL):
- global li
- global text_box
- global terminations
- if len(terminations) != 0:
- if ALL == 1:
- for i in range(len(terminations)):
- quarantaene.decode_base64(terminations[i])
- text_box.insert(END, "[ + ] Successfully restored\n" +
- terminations[i] + "\n", 'positive')
- text_box.tag_config('positive', foreground="green")
- text_box.see(END)
- text_box.update()
- li.delete(0, len(terminations[i]))
- li.update()
- elif ALL == 0:
- quarantaene.decode_base64(file)
- li.delete(ACTIVE, len(file))
- text_box.insert(
- END, "[ + ] Successfully restored\n" + file + "\n", "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- terminations = glob.glob(quarantine_folder)
- for i in terminations:
- li.insert(END, i)
- li.update()
- else:
- text_box.insert(END, "[ - ] Unable to locate any files\n", "negative")
- text_box.tag_config("negative", foreground="red")
- text_box.see(END)
- text_box.update()
- def add_file_to_quarantine():
- global li
- global terminations
- file = askopenfilename()
- file = file.replace("/", "\\")
- quarantaene.encode_base64(file, file_to_quarantine)
- text_box.insert(END, "[ + ] Moved to quarantine:\n" +
- file + "\n", "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- li.update()
- k = 0
- while True:
- tmp = len(li.get(k))
- if tmp == 0:
- break
- else:
- li.delete(0, tmp)
- k += 1
- li.update()
- terminations = glob.glob(quarantine_folder)
- for i in terminations:
- li.insert(END, i)
- li.update()
- def scan_auto(file):
- time.sleep(3)
- try:
- f = open(file, "rb")
- content = f.read()
- f.close()
- content = create_md5(content)
- except MemoryError:
- f.close()
- return False
- except:
- f.close()
- return False
- signatures = open(large_signatures, "rb")
- try:
- if content in signatures.read(): # fastest solution
- signatures.close()
- return True
- else:
- signatures.close()
- return False
- except MemoryError:
- try:
- signatures.close()
- signatures = open(large_signatures, "rb")
- if content in signatures.readlines(): # again fast, but around 4 times slower than the fastest
- signatures.close()
- return True
- else:
- signatures.close()
- return False
- except MemoryError:
- signatures.close()
- signatures = open(large_signatures, "rb")
- while True: # slowest solution, but can read files sized over 2 GB
- tmp = signatures.readline()
- if tmp == b"":
- signatures.close()
- break
- if tmp == content:
- signatures.close()
- return True
- return False
- except:
- return False
- def scan():
- global text_box
- match = False
- file = askopenfilename()
- start = time.time()
- text_box.insert(END, "[ * ] Scanning " + file + "\n")
- text_box.see(END)
- text_box.update()
- try:
- f = open(file, "rb")
- content = f.read()
- f.close()
- content = create_md5(content)
- text_box.insert(END, "MD5-Hash: " + content.decode("utf-8") + "\n")
- text_box.see(END)
- text_box.update()
- except MemoryError:
- text_box.insert(END, "[ - ] Unable to create MD5-Hash:\n----->MemoryError!\n",
- 'negative')
- text_box.insert(END, "[ ! ] Only select files under 1 GB\n", "negative")
- text_box.tag_config('negative', foreground="red")
- text_box.see(END)
- text_box.update()
- return None
- except Exception as e:
- text_box.insert(END, "[!] Unable to handle problem\n[!] Try again/file might be corrupted\n", "negative")
- text_box.tag_config('negative', foreground="red")
- text_box.see(END)
- text_box.update()
- return None
- signatures = open(large_signatures, "rb")
- # runtime of a scan varies from system to system(time on the systems tested: 1s <= t <= 20s)
- try:
- if content in signatures.read(): # fastest solution
- signatures.close()
- match = True
- else:
- match = False
- signatures.close()
- except MemoryError:
- try:
- signatures.close()
- signatures = open(large_signatures, "rb")
- if content in signatures.readlines(): # again fast, but around 4 times slower than the fastest
- f.close()
- match = True
- else:
- signatures.close()
- match = False
- except MemoryError:
- signatures.close()
- signatures = open(large_signatures, "rb")
- while True: # slowest solution, but can read files sized over 2 GB
- tmp = signatures.readline()
- if tmp == b"":
- signatures.close()
- break
- if tmp == content:
- match = True
- signatures.close()
- except:
- text_box.insert(END, "[ - ] Something bad happened while performing the task\n",
- "negative")
- text_box.tag_config("negative", foreground="red")
- text_box.see(END)
- text_box.update()
- return None
- text_box.insert(
- END, "[ * ] Scan duration: {0}\n".format(round(time.time()-start, 2)))
- text_box.see(END)
- text_box.update()
- if match:
- quarantaene.encode_base64(file, file_to_quarantine)
- text_box.insert(END, "[ ! ] Threat found: {0}\n[ ! ] File was moved into quarantine",
- "important")
- text_box.tag_config("important", foreground="red")
- text_box.see(END)
- text_box.update()
- if not match:
- text_box.insert(END, "[ + ] No threat was found\n", "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- def create_md5(content):
- md = hashlib.md5()
- md.update(content)
- return bytes(md.hexdigest(), "utf-8")
- def link_collector(): # gets Links to refresh update-site;short spider
- global text_box
- u_list = []
- text_box.insert(END, "[ * ] Searching for update...\n")
- text_box.see(END)
- text_box.update()
- u = urllib.request.urlopen(
- "http://virusshare.com/hashes").read().decode("utf-8").splitlines()
- f = open(links_current, "w")
- for i in u:
- if "href='" in i:
- first = i.find("href='") + len("href='")
- i = i[first:]
- last = i.find("'")
- i = i[:last]
- if 'href="' in i:
- first = i.find('href="') + len('href="')
- i = i[first:]
- last = i.find('"')
- i = i[:last]
- if "VirusShare" in i:
- f.write("http://virusshare.com/hashes/" + i + "\n")
- f.close()
- return update()
- def update():
- global text_box
- zaehler = 0
- f = open(links_current, "r")
- f2 = open(links_downloaded, "r")
- files_downloaded = f2.read()
- f2.close()
- f2 = open(links_downloaded, "r")
- for i in f.read().splitlines():
- f2 = open(links_downloaded, "r")
- con = f2.read()
- f2.close()
- f2 = open(links_downloaded, "a")
- if i not in con:
- zaehler += 1
- f2.write(i + "\n")
- f2.close()
- text_box.insert(END, "[ * ] Download of:\n"+i)
- text_box.see(END)
- text_box.update()
- signatures = open(large_signatures, "a")
- url = i
- tmp = urllib.request.urlopen(url).read().decode("utf-8").splitlines()
- for j in tmp:
- if j[0] != '#':
- signatures.write(j + "\n")
- signatures.close()
- if zaehler == 0:
- text_box.insert(END, "[ * ] No new updates were found\n")
- text_box.see(END)
- text_box.update()
- else:
- text_box.insert(
- END, "[ + ] {0} new updates were made\n".formate(zaehler), "positive")
- text_box.tag_config("positive", foreground="green")
- text_box.see(END)
- text_box.update()
- def closing():
- main.destroy()
- sys.exit()
- def button_action_handler(s):
- global files_len
- global text_box
- global t_time
- global fullscan_button
- global b_delete
- global b_delete_all
- global b_restore
- global b_restore_all
- global b_add_file
- global li
- global rb1
- global rb2
- global method
- if s == "rb1":
- method = 1
- rb1.place_forget()
- rb2.place_forget()
- if s == "rb2":
- method = 2
- rb2.place_forget()
- rb1.place_forget()
- if s == "delete":
- tb = Thread(target=delete, args=(li.get(ACTIVE), 0))
- tb.start()
- if s == "delete_all":
- tb = Thread(target=delete, args=(0, 1))
- tb.start()
- if s == "restore":
- tb = Thread(target=restore, args=(li.get(ACTIVE), 0))
- tb.start()
- if s == "restore_all":
- tb = Thread(target=restore, args=(0, 1))
- tb.start()
- if s == "add_file":
- tb = Thread(target=add_file_to_quarantine)
- tb.start()
- if s == "update_button":
- tb = Thread(target=link_collector)
- tb.start()
- if s == "scan_button":
- tb = Thread(target=scan)
- tb.start()
- if s == "fullscan_button":
- if files_len == 0:
- text_box.insert(END, "[ ! ] Preparing program\n", "important")
- text_box.see(END)
- text_box.update()
- elif files_len < len(files):
- text_box.insert(END, "[ ! ] One scan is already in action\n", "important")
- text_box.see(END)
- text_box.update()
- else:
- fullscan_button["state"] = "disabled"
- t_time = time.time()
- text_box.insert(END, "[ ! ] Got {0} files to scan\n".format(
- files_len), 'important')
- text_box.tag_config("important", foreground="red")
- text_box.update()
- text_box.insert(END, "[ * ] Scan might last for hours...\n")
- text_box.see(END)
- text_box.update()
- tb1 = Thread(target=full_scan, args=(1,))
- tb1.start()
- time.sleep(1)
- tb2 = Thread(target=full_scan, args=(2,))
- tb2.start()
- time.sleep(1)
- tb3 = Thread(target=full_scan, args=(3,))
- tb3.start()
- time.sleep(1)
- tb4 = Thread(target=full_scan, args=(4,))
- tb4.start()
- time.sleep(1)
- tb5 = Thread(target=full_scan, args=(5,))
- tb5.start()
- time.sleep(1)
- tb6 = Thread(target=full_scan, args=(6,))
- tb6.start()
- time.sleep(1)
- tb7 = Thread(target=full_scan, args=(7,))
- tb7.start()
- time.sleep(1)
- tb8 = Thread(target=full_scan, args=(8,))
- tb8.start()
- if s == "quarantine_button":
- if li.winfo_viewable() == 0:
- b_delete.place(x=570, y=70)
- b_delete_all.place(x=570, y=95)
- b_restore.place(x=570, y=120)
- b_restore_all.place(x=570, y=145)
- b_add_file.place(x=570, y=170)
- li.place(x=570, y=18.5)
- tb = Thread(target=quarantine)
- tb.start()
- if li.winfo_viewable() == 1:
- b_delete.place_forget()
- b_delete_all.place_forget()
- b_restore.place_forget()
- b_restore_all.place_forget()
- b_add_file.place_forget()
- li.place_forget()
- if s == "quit_button":
- tb = Thread(target=closing)
- tb.start()
- def gui_thread():
- global main
- global update_button
- global scan_button
- global fullscan_button
- global quit_button
- global text_box
- global e
- global files_len
- global files
- global li
- global b_delete
- global b_delete_all
- global b_restore
- global b_restore_all
- global b_add_file
- global rb1
- global rb2
- global method
- global bgc
- global fgc
- global special_text
- main = tkinter.Tk()
- main.title("AntiVirus")
- main.wm_iconbitmap("")
- main.configure(bg=bgc)
- main.geometry("750x205") # width x height
- main.resizable(False, False)
- # main.overrideredirect(1)
- hoehe = 2
- breite = 20
- # Buttons
- update_button = tkinter.Button(main, bg=bgc, fg=fgc, text="Update",
- command=lambda: button_action_handler("update_button"), height=hoehe, width=breite)
- update_button.grid(row=0, column=0)
- scan_button = tkinter.Button(main, bg=bgc, fg=fgc, text="Scan",
- command=lambda: button_action_handler("scan_button"), height=hoehe, width=breite)
- scan_button.grid(row=1, column=0)
- fullscan_button = tkinter.Button(main, bg=bgc, fg=fgc, text="Full scan",
- command=lambda: button_action_handler("fullscan_button"), height=hoehe, width=breite)
- fullscan_button.grid(row=2, column=0)
- quarantine_button = tkinter.Button(main, bg=bgc, fg=fgc, text="Quarantine",
- command=lambda: button_action_handler("quarantine_button"), height=hoehe, width=breite)
- quarantine_button.grid(row=3, column=0)
- quit_button = tkinter.Button(main, bg=bgc, fg=fgc, text="Close",
- command=lambda: button_action_handler("quit_button"), height=hoehe, width=breite)
- quit_button.grid(row=4, column=0, sticky="w")
- b_delete = tkinter.Button(
- main, bg=bgc, fg=fgc, text="Remove current", height=0, width=25, justify=CENTER)
- b_delete_all = tkinter.Button(
- main, bg=bgc, fg=fgc, text="Remove all", height=0, width=25, justify=CENTER)
- b_restore = tkinter.Button(
- main, bg=bgc, fg=fgc, text="Restore current", height=0, width=25, justify=CENTER)
- b_restore_all = tkinter.Button(
- main, bg=bgc, fg=fgc, text="Restore all", height=0, width=25, justify=CENTER)
- b_add_file = tkinter.Button(main, bg=bgc, fg=fgc, text="Add file", height=0, width=25,
- justify=CENTER)
- b_delete.place(x=570, y=70)
- b_delete_all.place(x=570, y=95)
- b_restore.place(x=570, y=120)
- b_restore_all.place(x=570, y=145)
- b_add_file.place(x=570, y=170)
- b_delete.place_forget()
- b_delete_all.place_forget()
- b_restore.place_forget()
- b_restore_all.place_forget()
- b_add_file.place_forget()
- # Text
- text_box = tkinter.scrolledtext.ScrolledText(main)
- text_box.configure(bg=bgc)
- text_box.configure(fg=fgc)
- text_box.place(height=205, width=419, x=150, y=0)
- # Listbox
- li = tkinter.Listbox(main, height=3, width=29)
- li.place(x=570, y=18.5)
- li.place_forget()
- # Entries
- e = tkinter.Entry(main, width=30)
- e.place(x=570, y=0)
- e["justify"] = CENTER
- e.insert(0, "")
- e["bg"] = bgc
- e["fg"] = fgc
- # Intro
- text_box.insert(END, "VIP")
- text_box.tag_config("VIP", background=special)
- text_box.insert(END, "[ + ] Preparing the program\n", 'positive')
- text_box.tag_config('positive', foreground='green')
- text_box.see(END)
- text_box.update()
- text_box.insert(
- END, "[ ! ] You might have to wait for a bit\n", 'important')
- text_box.tag_config('important', foreground="red")
- text_box.see(END)
- text_box.update()
- # row_counter += 3
- main.mainloop()
- # Executing Threads
- t_main = Thread(target=gui_thread) # Main Thread
- t_files = Thread(target=ScanSystemFiles)
- # t_clock = Thread(target=clock_thread)
- t_main.start()
- time.sleep(1)
- # t_clock.start()
- # time.sleep(5)
- # print(t_main.isAlive())
- t_files.start()