diff --git a/1693a7fa5b5993d87647a2d92c709c5c.png b/1693a7fa5b5993d87647a2d92c709c5c.png
new file mode 100644
index 0000000000000000000000000000000000000000..946ccd5779dda40c4b786bb277c8faadf4eb409d
Binary files /dev/null and b/1693a7fa5b5993d87647a2d92c709c5c.png differ
diff --git a/AppData/result10.txt b/AppData/result10.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb99623f3eeded4a3f15b24804f03ae4ff049d7e
--- /dev/null
+++ b/AppData/result10.txt
@@ -0,0 +1,2 @@
+1111
+0.0100
\ No newline at end of file
diff --git a/AppData/result11.txt b/AppData/result11.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b2f75a8df370c23b3cda74cc441672637c48e32
--- /dev/null
+++ b/AppData/result11.txt
@@ -0,0 +1,2 @@
+123
+0.0020
\ No newline at end of file
diff --git a/AppData/result12.txt b/AppData/result12.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb99623f3eeded4a3f15b24804f03ae4ff049d7e
--- /dev/null
+++ b/AppData/result12.txt
@@ -0,0 +1,2 @@
+1111
+0.0100
\ No newline at end of file
diff --git a/AppData/result4.txt b/AppData/result4.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e08b91e2f0a646058b8a42f9687824082ad732f2
--- /dev/null
+++ b/AppData/result4.txt
@@ -0,0 +1,2 @@
+123
+0.5355
\ No newline at end of file
diff --git a/AppData/result5.txt b/AppData/result5.txt
new file mode 100644
index 0000000000000000000000000000000000000000..58fec933a1a864962918b6073c5c54c59608cd75
--- /dev/null
+++ b/AppData/result5.txt
@@ -0,0 +1,2 @@
+123
+0.5455
\ No newline at end of file
diff --git a/AppData/result6.txt b/AppData/result6.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6911ace5bf6304710220ad87ee25b694c56a1591
--- /dev/null
+++ b/AppData/result6.txt
@@ -0,0 +1,2 @@
+123
+0.5365
\ No newline at end of file
diff --git a/AppData/result7.txt b/AppData/result7.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b2f75a8df370c23b3cda74cc441672637c48e32
--- /dev/null
+++ b/AppData/result7.txt
@@ -0,0 +1,2 @@
+123
+0.0020
\ No newline at end of file
diff --git a/AppData/result8.txt b/AppData/result8.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb99623f3eeded4a3f15b24804f03ae4ff049d7e
--- /dev/null
+++ b/AppData/result8.txt
@@ -0,0 +1,2 @@
+1111
+0.0100
\ No newline at end of file
diff --git a/AppData/result9.txt b/AppData/result9.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b2f75a8df370c23b3cda74cc441672637c48e32
--- /dev/null
+++ b/AppData/result9.txt
@@ -0,0 +1,2 @@
+123
+0.0020
\ No newline at end of file
diff --git a/AttackAlgorithms/BruteForceAttackAlgorithm.py b/AttackAlgorithms/BruteForceAttackAlgorithm.py
index 944e95ece31904765ea4fc6f8a16689c9d71bcda..1eb738b311bffadd573ea440d2029528cfc033d8 100644
--- a/AttackAlgorithms/BruteForceAttackAlgorithm.py
+++ b/AttackAlgorithms/BruteForceAttackAlgorithm.py
@@ -97,13 +97,10 @@ class BruteForceAttackAlgorithm():
         
             #Compare passwords to check if it has cracked
             if(hash == self.hash_to_crack):
-                print(f"Found Password: {password}")
-                
                 #stops and prints timer
                 self.end = time.time()
                 self.time = self.end - self.start
-                print('{:.4f} seconds'.format(self.time))
-
+                #saves result to file
                 self.save_output(password)
                 self.found.set()
  
@@ -147,7 +144,6 @@ class BruteForceAttackAlgorithm():
     returns: none
     """
     def main(self):
-        print(" -= Starting brute force =- ")
         self.brute_force()
         
             
diff --git a/AttackAlgorithms/__pycache__/BruteForceAttackAlgorithm.cpython-38.pyc b/AttackAlgorithms/__pycache__/BruteForceAttackAlgorithm.cpython-38.pyc
index e9813cf3c3f96bc86fb442f95588584f6285ca23..dcdd3951d7376c0a28ad7156ebb0d5f21cedfd55 100644
Binary files a/AttackAlgorithms/__pycache__/BruteForceAttackAlgorithm.cpython-38.pyc and b/AttackAlgorithms/__pycache__/BruteForceAttackAlgorithm.cpython-38.pyc differ
diff --git a/AttackAlgorithms/__pycache__/DictionaryAttackAlgorithm.cpython-38.pyc b/AttackAlgorithms/__pycache__/DictionaryAttackAlgorithm.cpython-38.pyc
index 536f3abf7bd80fe79e64fabbcb2253894f9dab36..017b382c559c03ef386c268f988aaea0db6a1980 100644
Binary files a/AttackAlgorithms/__pycache__/DictionaryAttackAlgorithm.cpython-38.pyc and b/AttackAlgorithms/__pycache__/DictionaryAttackAlgorithm.cpython-38.pyc differ
diff --git a/AttackAlgorithms/__pycache__/HybridAttackAlgorithm.cpython-38.pyc b/AttackAlgorithms/__pycache__/HybridAttackAlgorithm.cpython-38.pyc
index 4d7b257640ad0ef285e8c36ef0b3c1c0e958acbe..d840adcb44ed8f9669528620fd80b7d397485cb1 100644
Binary files a/AttackAlgorithms/__pycache__/HybridAttackAlgorithm.cpython-38.pyc and b/AttackAlgorithms/__pycache__/HybridAttackAlgorithm.cpython-38.pyc differ
diff --git a/AttackAlgorithms/__pycache__/RulebasedAttackAlgorithm.cpython-38.pyc b/AttackAlgorithms/__pycache__/RulebasedAttackAlgorithm.cpython-38.pyc
index 4dec736bcba875dcd3b2539c77d4c7ffdfcffa7c..f706e5178d0bb5aa5c8f4369b6f792bb727c52a4 100644
Binary files a/AttackAlgorithms/__pycache__/RulebasedAttackAlgorithm.cpython-38.pyc and b/AttackAlgorithms/__pycache__/RulebasedAttackAlgorithm.cpython-38.pyc differ
diff --git a/GUIDesign.py b/GUIDesign.py
index 928a03f7bef9b0143db9c8e3d2f061fcb19348ea..6928c0b13cb16ffae7fa1f7817b73b0b0b8e3e8f 100644
--- a/GUIDesign.py
+++ b/GUIDesign.py
@@ -12,7 +12,6 @@ import os
 import multiprocessing
 from multiprocessing import Process, Event
 import random
-import psutil
 import subprocess
 
 #PyQt6 imports
@@ -102,9 +101,9 @@ class BruteForceWorker(QRunnable):
         with open(filename, "r") as result:
             for idx, data in enumerate(result): 
                 if(idx == 1):
-                    self.output.append(f" {data} sec")
+                    self.output.append(f"\t -= {data} sec =-")
                 else:
-                    self.output.append(f" Password: {data}")
+                    self.output.append(f"\t -= Password found: {data} =-")
     
     """
     Name: brute_force_cpu
@@ -115,6 +114,7 @@ class BruteForceWorker(QRunnable):
     def brute_force_cpu(self):
         #data with starting points
         data = self.split_data()
+        
         #found event triggered when password found
         self.found = Event()
         #creates processes passing in needed data
@@ -124,7 +124,7 @@ class BruteForceWorker(QRunnable):
 
             #Creating process using the dictionary main function
             p = multiprocessing.Process(target=dictionary.main)
-            self.output.append(f" -= Starting process {i} =-")
+            self.output.append(f"\t-= Starting process {i} =-")
             self.process_list.append(p)
 
         #Starts processes
@@ -136,7 +136,7 @@ class BruteForceWorker(QRunnable):
 
         #Terminates processes
         for process in self.process_list:
-            print("Terminating")
+            print("\t-= Terminating =-")
             process.terminate()
 
         #Waits for processes to finish terminating
@@ -145,7 +145,8 @@ class BruteForceWorker(QRunnable):
             
         #Finishing up
         self.process_result()
-        self.output.append(" Attack Finished ")
+        self.output.append("\t-= Attack Finished =- ")
+        self.process_list.clear()
         print("Done")
     
     """
@@ -163,15 +164,30 @@ class BruteForceWorker(QRunnable):
     
     """
     Name: run
-    Description: Starts brute force attack using process amount with process terminatation(syncronisation)
+    Description: Starts brute force attack selecting the CPU and check for a hash_file
     Parameters: self 
     returns: none
     """
     def run(self):
-        self.output.append("-= Starting Brute Force Attack =-")
-        if(self.attack_options.cpu):
-            self.output.append(" Using CPU")
-            self.brute_force_cpu()
+        hash_file = list()
+        #if there is no has file then run single hash crack
+        if(self.attack_options.hash_file_location == ""):
+            self.output.append("-= Starting Brute Force Attack =-")
+            if(self.attack_options.cpu):
+                self.output.append(" Using CPU")
+                self.brute_force_cpu()
+        else:
+            with open(self.attack_options.hash_file_location) as file:
+                hash_file = [line.strip() for line in file]
+
+            for hash in hash_file:
+                self.attack_options.hash_value = hash
+                self.output.append("-= Starting Brute Force Attack =-")
+                if(self.attack_options.cpu):
+                    self.output.append("\tUsing CPU")
+                    self.brute_force_cpu()
+
+
 
 """
 Class Name: DictionaryWorker
@@ -307,11 +323,11 @@ class DictionaryWorker(QRunnable):
     Parameters: self 
     returns: none
     """
-    def pause_process(self):
-        print("Pauseing Application")
-        for id in self.pid:
-            p = psutil.Process(id)
-            p.suspend()
+    # def pause_process(self):
+    #     print("Pauseing Application")
+    #     for id in self.pid:
+    #         p = psutil.Process(id)
+    #         p.suspend()
         
     """
     Name: resume_process
@@ -319,23 +335,36 @@ class DictionaryWorker(QRunnable):
     Parameters: self 
     returns: none
     """
-    def resume_process(self):
-        print("Resuming Application")
-        for id in self.pid:
-            p = psutil.Process(id)
-            p.resume()
+    # def resume_process(self):
+    #     print("Resuming Application")
+    #     for id in self.pid:
+    #         p = psutil.Process(id)
+    #         p.resume()
        
     """
     Name: run
-    Description: Starts dictionary attack selecting the CPU
+    Description: Starts dictionary attack selecting the CPU and check for a hash_file
     Parameters: self 
     returns: none
     """
     def run(self):
-        self.output.append("-= Starting Dictionary Attack =-")
-        if(self.attack_options.cpu):
-            self.output.append(" Using CPU")
-            self.dictionary_cpu()
+        hash_file = list()
+        #if there is no has file then run single hash crack
+        if(self.attack_options.hash_file_location == ""):
+            self.output.append("-= Starting Dictionary Attack =-")
+            if(self.attack_options.cpu):
+                self.output.append(" Using CPU")
+                self.dictionary_cpu()
+        else:
+            with open(self.attack_options.hash_file_location) as file:
+                hash_file = [line.strip() for line in file]
+
+            for hash in hash_file:
+                self.attack_options.hash_value = hash
+                self.output.append("-= Starting Dictionary Attack =-")
+                if(self.attack_options.cpu):
+                    self.output.append("\tUsing CPU")
+                    self.dictionary_cpu() 
 
 """
 Class Name: HybridWorker
@@ -487,15 +516,29 @@ class HybridWorker(QRunnable):
 
     """
     Name: run
-    Description: Starts hybrid attack selecting the CPU
+    Description: Starts hybrid attack selecting the CPU and check for a hash_file
     Parameters: self 
     returns: none
     """
     def run(self):
-        self.output.append("-= Starting Hybrid Attack =-")
-        if(self.attack_options.cpu):
-            self.output.append(" Using CPU")
-            self.hybrid_cpu()
+        hash_file = list()
+        #if there is no has file then run single hash crack
+        if(self.attack_options.hash_file_location == ""):
+            self.output.append("-= Starting Hybrid Attack =-")
+            if(self.attack_options.cpu):
+                self.output.append(" Using CPU")
+                self.hybrid_cpu()
+        else:
+            with open(self.attack_options.hash_file_location) as file:
+                hash_file = [line.strip() for line in file]
+
+            for hash in hash_file:
+                
+                self.attack_options.hash_value = hash
+                self.output.append("-= Starting Hybrid Attack =-")
+                if(self.attack_options.cpu):
+                    self.output.append("\tUsing CPU")
+                    self.hybrid_cpu() 
 
 """
 Class Name: RuleBasedWorker
@@ -651,14 +694,28 @@ class RuleBasedWorker(QRunnable):
 
     """
     Name: run
-    Description: Starts rule based attack selecting the CPU
+    Description: Starts rule based attack selecting the CPU and check for a hash_file
     Parameters: self 
     returns: none
     """
     def run(self):
-        if(self.attack_options.cpu):
-            self.output.append(" Using CPU")
-            self.rulebase_cpu()
+        hash_file = list()
+        if(self.attack_options.hash_file_location == ""):
+            self.output.append("-= Starting Rule-Based Attack =-")
+            if(self.attack_options.cpu):
+                self.output.append(" Using CPU")
+                self.rulebase_cpu()
+        else:
+            with open(self.attack_options.hash_file_location) as file:
+                hash_file = [line.strip() for line in file]
+
+            for hash in hash_file:
+                
+                self.attack_options.hash_value = hash
+                self.output.append("-= Starting Hybrid Attack =-")
+                if(self.attack_options.cpu):
+                    self.output.append("\tUsing CPU")
+                    self.rulebase_cpu() 
 
 """
 Class Name: RainbowTableWorker
@@ -669,13 +726,61 @@ class RainbowTableAttack(QRunnable):
     def __init__(self, attack_options, output):
         self.attack_options = attack_options
         self.output = output;
+        self.filename = "C:\\Users\\ethan\\OneDrive\\Desktop\\Year3\\DSP\\Password_Cracker_App\\Rainbowcrack\\start.bat"
+        self.bat = None
+
+    """
+    Name: add_hash_to_bat
+    Description: Will add the input hash value to the bat file 
+    Parameters: self
+    returns: none
+    """
+    def add_hash_to_bat(self):
+        with open(self.filename, "r") as file:
+            self.bat = file.read()
+
+        self.bat= self.bat.replace("HASH", self.attack_options.hash_value)
+
+        with open(self.filename, "w") as file:
+            file.write(self.bat)            
+    
+    """
+    Name: remove_hash_from_bat
+    Description: Will add the HASH keyword back to the bat file for future attacks
+    Parameters: self
+    returns: none
+    """
+    def remove_hash_from_bat(self):
+        with open(self.filename, "r") as file:
+            self.bat = file.read()
+
+        self.bat = self.bat.replace(self.attack_options.hash_value, "HASH")
+
+        with open(self.filename, "w") as file:
+            file.write(self.bat)           
     
+    """
+    Name: rainbowtable_cpu
+    Description: Will start the rainbow table attack using RainbowCrack through a bat file
+    Parameters: self
+    returns: none
+    """
     def rainbowtable_cpu(self):
-        command = f"Rainbowcrack/rtgen -h {self.attack_options.hash}"
-        attack = subprocess.Popen()
+        #Add hash value to bat file
+        self.add_hash_to_bat()
+        #Start attack from a bat file
+        p = subprocess.Popen(self.filename, stdout=subprocess.PIPE, shell=True)
+        p.wait()
+        result = p.stdout.read()
+        #remove hash value from bat file
+        self.remove_hash_from_bat()
+        #process output of command prompt
+        self.output.append(result.decode())
+        self.output.append("-= Rainbow Crack output =-")
+
+
     
     def run(self):
-        #
         if(self.attack_options.cpu):
             self.output.append(" Using CPU")
             self.rainbowtable_cpu()
@@ -733,7 +838,9 @@ class Ui_App(object):
     """
     def setupUi(self, App):
         App.setObjectName("App")
-        App.resize(1012, 696)
+        App.setFixedSize(1012, 696)
+        
+        
         palette = QtGui.QPalette()
         brush = QtGui.QBrush(QtGui.QColor(0, 120, 215))
         brush.setStyle(QtCore.Qt.BrushStyle.SolidPattern)
@@ -1148,6 +1255,7 @@ class Ui_App(object):
         elif(attack_selection == "Rainbow Table"):
             self.wordlistFrame.setEnabled(True) 
             self.charsetFrame.setEnabled(False)
+            self.attackOptionsBtn.setEnabled(False)
             self.wordlistLbl.setText("Rainbow table") 
             
         elif(attack_selection == "Markov Chain"):
@@ -1206,7 +1314,9 @@ class Ui_App(object):
         #Open file dialog box
         hash_file = QtWidgets.QFileDialog.getOpenFileName(None, 'Open password file', 'C:\\', '*.txt')
         #set text edit to wordlist location
-        self.hash_file_location = self.hashInputTxt.insertPlainText(hash_file[0])
+        self.hashInputTxt.insertPlainText(hash_file[0])
+        self.hash_file_location = hash_file[0]
+        print(self.hash_file_location)
         
     """
     Name: _browseWordlist
@@ -1336,11 +1446,10 @@ class Ui_App(object):
                 self.output.append(f"       - Rainbowtable: {self.attack_options.wordlist_location}")
                 self.output.append(f"       - Processes: {self.attack_options.core_count}")
 
-                pool = QThreadPool.globalInstance()
-                self.worker = RainbowTableAttack(self.attack_options, self.output)
+                rainbowtable=RainbowTableAttack(self.attack_options, self.output)
+                rainbowtable.run()
                 
-                pool.start(self.worker)
-
+        
             if(self.attack_options.attack_type == "Markov Chain"):
                 self.output.append(" Starting Attack ")
                 self.output.append(f"       - Hash: {self.attack_options.hash_value}")
diff --git a/Rainbowcrack/start.bat b/Rainbowcrack/start.bat
new file mode 100644
index 0000000000000000000000000000000000000000..31af342d05b410d4c74bcaa32fccc0325d9d1ebe
--- /dev/null
+++ b/Rainbowcrack/start.bat
@@ -0,0 +1,2 @@
+cd C:\\Users\\ethan\\OneDrive\\Desktop\\Year3\\DSP\\Password_Cracker_App\\Rainbowcrack
+rcrack.exe . -h HASH
\ No newline at end of file
diff --git a/test_data.txt b/test_data.txt
new file mode 100644
index 0000000000000000000000000000000000000000..381793ede232ffe8bdf77ccf337824b9c2f07f38
--- /dev/null
+++ b/test_data.txt
@@ -0,0 +1,2 @@
+40BD001563085FC35165329EA1FF5C5ECBDBBEEF
+011C945F30CE2CBAFC452F39840F025693339C42
\ No newline at end of file